특정 색상의 더 어둡거나 밝은 색상 변형을 어떻게 결정합니까?

StackOverflow https://stackoverflow.com/questions/97646

  •  01-07-2019
  •  | 
  •  

문제

시스템이나 사용자가 어떤 색조의 소스 색상을 지정하더라도 선택한 색상의 더 밝거나 어두운 변형을 해결하는 데 사용할 수 있는 간단한 알고리즘이 필요합니다.사용자 인터페이스 스타일을 지정하기 위해 Windows Live Messenger에 사용되는 효과와 유사합니다.

언어는 .net 3.5의 C#입니다.

댓글에 응답: 색상 형식은 (알파)RGB입니다.값을 바이트 또는 부동 소수점으로 사용합니다.

마킹 답변: 내 사용 맥락(몇 가지 간단한 UI 효과)에 대해 허용된 것으로 표시한 대답은 실제로 이 맥락에서 가장 간단합니다.그러나 더 복잡하고 정확한 답변에도 투표를 포기했습니다.고급 색상 작업을 수행하고 나중에 이 스레드를 찾는 사람은 반드시 이를 확인해야 합니다.고마워요.:)

도움이 되었습니까?

해결책

간단히 RGB 값에 레벨을 수정하려는 양을 곱하면 됩니다.색상 중 하나가 이미 최대 값인 경우 더 밝게 만들 수 없습니다(어쨌든 HSV 수학 사용).

이는 HSV로 전환한 다음 V를 수정하는 것보다 훨씬 적은 수학적 계산으로 정확히 동일한 결과를 제공합니다.이는 채도 손실을 원하지 않는 한 HSL로 전환한 다음 L을 수정하는 것과 동일한 결과를 제공합니다.

다른 팁

~ 안에 XNA가 있습니다 Color.Lerp 정적 방법 이는 두 색상의 차이로 나타납니다.

Lerp 두 부동소수점 사이의 차이 비율에 따라 첫 번째 부동소수점의 값을 변경하는 수학적 연산입니다.

다음은 이를 수행하는 확장 방법입니다. float:

public static float Lerp( this float start, float end, float amount)
{
    float difference = end - start;
    float adjusted = difference * amount;
    return start + adjusted;
}

따라서 RGB를 사용하여 두 색상 간의 간단한 lerp 작업은 다음과 같습니다.

public static Color Lerp(this Color colour, Color to, float amount)
{
    // start colours as lerp-able floats
    float sr = colour.R, sg = colour.G, sb = colour.B;

    // end colours as lerp-able floats
    float er = to.R, eg = to.G, eb = to.B;

    // lerp the colours to get the difference
    byte r = (byte) sr.Lerp(er, amount),
         g = (byte) sg.Lerp(eg, amount),
         b = (byte) sb.Lerp(eb, amount);

    // return the new colour
    return Color.FromArgb(r, g, b);
}

이를 적용하는 예는 다음과 같습니다.

// make red 50% lighter:
Color.Red.Lerp( Color.White, 0.5f );

// make red 75% darker:
Color.Red.Lerp( Color.Black, 0.75f );

// make white 10% bluer:
Color.White.Lerp( Color.Blue, 0.1f );

HSL(Hue/Saturation/Lightness)이라고도 하는 HSV(Hue/Saturation/Value)는 색상 표현의 차이일 뿐입니다.

이 표현을 사용하면 밝기를 조정하는 것이 더 쉽습니다.따라서 RGB에서 HSV로 변환하고 'V'를 밝게 한 다음 다시 RGB로 변환합니다.

아래는 변환할 C 코드입니다.

void RGBToHSV(unsigned char cr, unsigned char cg, unsigned char cb,double *ph,double *ps,double *pv)
{
double r,g,b;
double max, min, delta;

/* convert RGB to [0,1] */

r = (double)cr/255.0f;
g = (double)cg/255.0f;
b = (double)cb/255.0f;

max = MAXx(r,(MAXx(g,b)));
min = MINx(r,(MINx(g,b)));

pv[0] = max;

/* Calculate saturation */

if (max != 0.0)
    ps[0] = (max-min)/max;
else
    ps[0] = 0.0; 

if (ps[0] == 0.0)
{
    ph[0] = 0.0f;   //UNDEFINED;
    return;
}
/* chromatic case: Saturation is not 0, so determine hue */
delta = max-min;

if (r==max)
{
    ph[0] = (g-b)/delta;
}
else if (g==max)
{
    ph[0] = 2.0 + (b-r)/delta;
}
else if (b==max)
{
    ph[0] = 4.0 + (r-g)/delta;
}
ph[0] = ph[0] * 60.0;
if (ph[0] < 0.0)
    ph[0] += 360.0;
}

void HSVToRGB(double h,double s,double v,unsigned char *pr,unsigned char *pg,unsigned char *pb)
{
int i;
double f, p, q, t;
double r,g,b;

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

pr[0]=(unsigned char)r;
pg[0]=(unsigned char)g;
pb[0]=(unsigned char)b;
}

리치 뉴먼 HSL 색상에 대해 논의합니다. 그의 블로그에 있는 .NET System. Drawing.Color와 심지어 HSLColor 클래스를 제공합니다 그것은 당신을 위해 모든 일을 합니다.System.드로잉.Color를 HSLColor로 변환하고 광도에 대해 값을 더하거나 뺀 다음 앱에서 사용할 수 있도록 다시 System.드로잉.Color로 변환합니다.

색상을 HSL 색상 공간으로 변환하고 거기에서 조작한 다음 선택한 색상 공간(대부분 RGB)으로 다시 변환할 수 있습니다.

색상이 밝을수록 L값이 높고, 어두울수록 L값이 낮습니다.

관련 내용과 모든 방정식은 다음과 같습니다.

http://en.wikipedia.org/wiki/HSL_color_space

또 다른 방법은 단순히 색상을 흰색이나 검정색으로 보간하는 것입니다.이렇게 하면 색상의 채도가 약간 떨어지지만 계산하는 것이 더 저렴합니다.

System.Windows.Forms에서 ControlPaint.Dark() 및 .Light()를 사용했습니다.

나는 어디에서나 매우 일반적이기 때문에 바이트 값(0~255)으로 RGB를 사용하고 있다고 추측합니다.

더 밝게 하려면 흰색 RGB를 사용하여 RGB 값의 평균을 구합니다.또는 밝기를 어느 정도 조절하려면 일정 비율로 혼합하세요.허락하다 f 0.0에서 1.0까지 다양합니다. 그런 다음:

Rnew = (1-f)*R + f*255
Gnew = (1-f)*G + f*255
Bnew = (1-f)*B + f*255

더 어둡게 하려면 검정색 RGB를 사용하세요. 모두 0이므로 수학이 더 쉬워집니다.

결과를 다시 바이트로 변환하는 것과 같은 세부 사항은 생략합니다. 아마도 여러분이 원할 것입니다.

RGB 색상을 사용하는 경우 이 색상 매개변수를 다음과 같이 변환합니다. HSL (색조, 채도, 밝기), 밝기 매개변수를 수정한 다음 다시 RGB로 변환합니다.Google을 검색하면 이러한 색상 표현 변환(RGB에서 HSL로 또는 그 반대로)을 수행하는 방법에 대한 많은 코드 샘플을 찾을 수 있습니다.

제가 빨리 찾은 내용은 다음과 같습니다.http://bytes.com/forum/thread250450.html

색상을 RGB로 가져온다고 가정하면 먼저 이를 HSV(색조, 채도, 명도) 색상 공간으로 변환합니다.그런 다음 값을 늘리거나 줄여 색상의 더 밝거나 어두운 음영을 생성합니다.그런 다음 다시 RGB로 변환합니다.

색상이 RGB 형식(또는 아마도 CMYK)인 경우 색상의 각 구성 요소 값을 늘리는 매우 조잡한 방법을 사용할 수 있습니다.예를 들어, HTML 색상은 세 개의 두 자리 16진수로 표시됩니다.#ff0000은 밝은 빨간색을 제공하며 #ff5555(더 밝은 빨간색 제공)와 같이 G 및 B 구성 요소의 값을 같은 양만큼 증가시켜 희미해질 수 있습니다.아마도 HSL(색상, 채도 및 밝기) 색상의 경우 L 구성 요소를 높일 수 있지만 확실하게 말할 수는 없습니다.저는 이 색 공간에 익숙하지 않습니다.

하지만 내가 말했듯이 이 방법은 매우 조잡하다.내 기억에 따르면 Live Messenger에 대해 Windows Presentation Foundation(WPF, .NET 3.0의 일부)에서 매우 쉽게 적용할 수 있는 그라데이션을 수행하려고 하는 것 같습니다.WPF는 선형 및 방사형 그래디언트를 포함하여 다양한 유형의 그래디언트 브러시를 지원합니다.

Adam Nathan의 책을 적극 추천합니다. Windows 프레젠테이션 파운데이션 출시 WPF에 대한 훌륭하고 철저한 소개입니다.

HTH

색상의 변형은 HSL/HSV에서 더 잘 수행됩니다.

좋은 테스트는 RGB 공간과 HSL 공간의 두 동등한 값 사이를 보간하는 것입니다.HSL 공간의 램프는 자연스러운 진행처럼 보입니다.RGB 공간에서는 일반적으로 매우 부자연스러워 보입니다.HSL은 RGB보다 시각적 색 공간 인식에 훨씬 더 잘 매핑됩니다.

HSV 또는 다른 색상 공간으로 변환하는 아이디어는 좋아 보이고 정확한 색상 작업에 필요할 수 있지만 일반적인 목적에서는 RGB 작업 오류가 중요하지 않을 수 있습니다.또한 경계 사례를 처리하는 것도 어려울 수 있습니다.RGB는 큐브 모양의 공간이지만 HSV는 그렇지 않습니다.바이트 값으로 작업하는 경우 공백 간에 다대일 및 일대다 매핑이 ​​가능합니다.이는 응용 프로그램에 따라 문제가 될 수도 있고 그렇지 않을 수도 있습니다.YMMV

이것 웹사이트 BCL C# System.Windows.Forms 네임스페이스 내에서 ControlPaint 클래스를 사용할 수 있다는 점을 참고하세요.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top