代码之家  ›  专栏  ›  技术社区  ›  Edenia

绘制HSV渐变失败

  •  1
  • Edenia  · 技术社区  · 11 年前

    对于绘图过程,我有以下三个功能:

    void setpen(R, G, B) -设置当前笔刷的颜色

    void putpixel(X, Y) -使用画笔将像素置于X Y

    我正在尝试绘制HSV渐变:

    enter image description here

    使用这对代码:

    int S, H;
    
    for(S = 0; S<255; S++)
    {
        for(H = 0; H<255; H++)
        {
            setpen(S, H, H);
            putpixel(S, H);
        }
    }
    

    但从这段代码中得出的梯度是:

    enter image description here

    看起来并不糟糕,但这不是我真正想要的结果。正如我所见,右上方有一些正确的地方。。但在左下角它是青色的。 拜托,我的代码有什么问题?

    2 回复  |  直到 11 年前
        1
  •  3
  •   Nelfeal    11 年前

    从您所展示的内容来看,您需要一个具有固定色调(红色)、饱和度上升和值正确的渐变。

    当您使用 H = 0 (红色):
    - R = V
    - G = B = V * (1 - S)

    在你的情况下,对一些人来说 x y 在里面 [0; 255] 您需要以下内容:
    - V = x 因此 R = x ;
    - S = 255-y 因此 G = B = x * y .

    所以你可以把电话改成 setpen 这样地:
    setpen(S, (H*S) / 255, (H*S) / 255);

        2
  •  2
  •   Woodrow Barlow    11 年前

    你使用的是变量S和H。我假设你打算用它来表示“饱和度”和“色调”,但你实际想要的是“饱和度”与“亮度”(或“值”),因为色调总是红色。从左到右(内部循环),我们的亮度将从零变为255。

    您需要一个函数将HSL转换为RGB。我从 this website 并将其复制如下。

    void HSLtoRGB( int *r, int *g, int *b, int h, int s, int l )
    {
        int i;
        double f, p, q, t;
        if( s == 0 ) {
            // achromatic (grey)
            *r = *g = *b = l;
            return;
        }
        h /= 60.0;          // sector 0 to 5
        i = floor( h );
        f = h - i;          // factorial part of h
        p = l * ( 255 - s );
        q = l * ( 255 - s * f );
        t = l * ( 255 - s * ( 1 - f ) );
        switch( i ) {
            case 0:
                *r = (int) l;
                *g = (int) t;
                *b = (int) p;
                break;
            case 1:
                *r = (int) q;
                *g = (int) l;
                *b = (int) p;
                break;
            case 2:
                *r = (int) p;
                *g = (int) l;
                *b = (int) t;
                break;
            case 3:
                *r = (int) p;
                *g = (int) q;
                *b = (int) l;
                break;
            case 4:
                *r = (int) t;
                *g = (int) p;
                *b = (int) l;
                break;
            default:        // case 5:
                *r = (int) l;
                *g = (int) p;
                *b = (int) q;
                break;
        }
    }
    

    要将其绑定到代码中,只需执行以下操作:

    int H, S, L;
    H = 0; // ranges from 0 to 359 (degrees), 0 == red
    for(S = 0; S<255; S++)
    {
        for(L = 0; L<255; L++)
        {
            int r, g, b;
            HSLtoRGB(&r, &g, &b, H, S, L);
            setpen(r, g, b);
            putpixel(L, 255-S);
        }
    }