your programing

RGB 색상의 이동 색상

lovepro 2023. 6. 11. 16:46
반응형

RGB 색상의 이동 색상

저는 RGB 색상의 색상을 바꾸는 기능을 쓰려고 합니다.특히 iOS 앱에서 사용하고 있지만, 수학은 보편적입니다.

아래 그래프는 색상과 관련하여 R, G 및 B 값이 어떻게 변화하는지 보여줍니다.

색상 간 RGB 값 그래프

그것을 보니 색을 다른 색 형식으로 변환하지 않고 색을 바꾸는 기능을 쓰는 것이 비교적 간단해야 할 것 같고, 더 많은 오류(색상에 작은 변화를 계속 적용하면 문제가 될 수 있음)가 발생할 것 같고, 계산 비용이 더 많이 들 것 같습니다.

제가 지금까지 가지고 있는 것 중에 어떤 종류의 효과가 있는지 보여드리겠습니다.순수한 노란색, 청록색 또는 자홍색에서 전환하는 경우에는 완벽하게 작동하지만, 그렇지 않으면 일부 지역에서는 약간 끈적거립니다.

Color4f ShiftHue(Color4f c, float d) {
    if (d==0) {
        return c;
    }
    while (d<0) {
        d+=1;
    }

    d *= 3;

    float original[] = {c.red, c.green, c.blue};
    float returned[] = {c.red, c.green, c.blue};

    // big shifts
    for (int i=0; i<3; i++) {
        returned[i] = original[(i+((int) d))%3];
    }
    d -= (float) ((int) d);
    original[0] = returned[0];
    original[1] = returned[1];
    original[2] = returned[2];

    float lower = MIN(MIN(c.red, c.green), c.blue);
    float upper = MAX(MAX(c.red, c.green), c.blue);

    float spread = upper - lower;
    float shift  = spread * d * 2;

    // little shift
    for (int i = 0; i < 3; ++i) {
        // if middle value
        if (original[(i+2)%3]==upper && original[(i+1)%3]==lower) {
            returned[i] -= shift;
            if (returned[i]<lower) {
                returned[(i+1)%3] += lower - returned[i];
                returned[i]=lower;
            } else
                if (returned[i]>upper) {
                    returned[(i+2)%3] -= returned[i] - upper;
                    returned[i]=upper;
                }
            break;
        }
    }

    return Color4fMake(returned[0], returned[1], returned[2], c.alpha);
}

UIColors로 이 작업을 수행할 수 있으며 다음과 같은 방법으로 색상을 변경할 수 있습니다.

CGFloat hue;
CGFloat sat;
CGFloat bri;
[[UIColor colorWithRed:parent.color.red green:parent.color.green blue:parent.color.blue alpha:1] getHue:&hue saturation:&sat brightness:&bri alpha:nil];
hue -= .03;
if (hue<0) {
    hue+=1;
}
UIColor *tempColor = [UIColor colorWithHue:hue saturation:sat brightness:bri alpha:1];
const float* components= CGColorGetComponents(tempColor.CGColor);
color = Color4fMake(components[0], components[1], components[2], 1);

하지만 iOS 5에서만 작동하기 때문에 그것에 열광하지 않습니다. 그리고 여러 색 객체를 할당하고 RGB에서 HSB로 변환하는 것 사이에서 그것은 꽤 지나친 것처럼 보입니다.

조회 테이블을 사용하게 되거나 애플리케이션의 색상을 미리 계산하게 될 수도 있지만, 제 코드가 작동할 수 있는 방법이 있는지 정말 궁금합니다.감사합니다!

RGB 색 공간은 큐브를 설명합니다.이 큐브를 대각선 축을 중심으로 (0,0,0)에서 (255,255,255)까지 회전하여 색상을 변경할 수 있습니다.결과 중 일부는 0 - 255 범위를 벗어나므로 잘라내야 합니다.

드디어 이 알고리즘을 코딩할 기회를 얻었습니다.그것은 파이썬으로 되어 있지만 당신이 원하는 언어로 번역하기 쉬울 것입니다.3D 회전 공식은 http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle 에서 제공되었습니다.

편집 : 이전에 제가 올린 코드를 보셨다면 무시해주세요.저는 회전에 대한 공식을 찾기가 너무 급해서 매트릭스 기반 솔루션을 공식으로 변환했습니다. 처음부터 매트릭스가 최고의 형태라는 것을 깨닫지 못했습니다.축 단위 벡터 값에 대한 상수 sqrt(1/3)를 사용하여 행렬 계산을 단순화했지만, 이것은 정신적으로 기준에 훨씬 가깝고 픽셀당 계산에서 더 단순합니다.apply뿐만 아니라.

from math import sqrt,cos,sin,radians

def clamp(v):
    if v < 0:
        return 0
    if v > 255:
        return 255
    return int(v + 0.5)

class RGBRotate(object):
    def __init__(self):
        self.matrix = [[1,0,0],[0,1,0],[0,0,1]]

    def set_hue_rotation(self, degrees):
        cosA = cos(radians(degrees))
        sinA = sin(radians(degrees))
        self.matrix[0][0] = cosA + (1.0 - cosA) / 3.0
        self.matrix[0][1] = 1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA
        self.matrix[0][2] = 1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA
        self.matrix[1][0] = 1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA
        self.matrix[1][1] = cosA + 1./3.*(1.0 - cosA)
        self.matrix[1][2] = 1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA
        self.matrix[2][0] = 1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA
        self.matrix[2][1] = 1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA
        self.matrix[2][2] = cosA + 1./3. * (1.0 - cosA)

    def apply(self, r, g, b):
        rx = r * self.matrix[0][0] + g * self.matrix[0][1] + b * self.matrix[0][2]
        gx = r * self.matrix[1][0] + g * self.matrix[1][1] + b * self.matrix[1][2]
        bx = r * self.matrix[2][0] + g * self.matrix[2][1] + b * self.matrix[2][2]
        return clamp(rx), clamp(gx), clamp(bx)

다음은 위의 몇 가지 결과입니다.

색상 회전 예제

http://www.graficaobscura.com/matrix/index.html 에서 동일한 아이디어의 다른 구현을 찾을 수 있습니다.

주석별 편집을 "모두"에서 "선형 근사 가능자"로 변경했습니다.
오프셋을 추가하는 2개를 편집합니다.


기본적으로, 당신이 원하는 단계는

RBG->HSV->Update hue->RGB

선형 행렬 변환(즉, 연관성이 있음)으로 근사할 수 있으므로, 잘못된 변환이나 정밀도 손실 없이 한 번의 단계로 수행할 수 있습니다.변환 행렬을 서로 곱하면 색을 변환하는 데 사용됩니다.

여기에 간단한 단계별 정보가 있습니다. http://beesbuzz.biz/code/hsv_color_transforms.php

다음은 C++ 코드입니다(채도 및 값 변환 제거).

Color TransformH(
    const Color &in,  // color to transform
    float H
)
{
  float U = cos(H*M_PI/180);
  float W = sin(H*M_PI/180);

  Color ret;
  ret.r = (.299+.701*U+.168*W)*in.r
    + (.587-.587*U+.330*W)*in.g
    + (.114-.114*U-.497*W)*in.b;
  ret.g = (.299-.299*U-.328*W)*in.r
    + (.587+.413*U+.035*W)*in.g
    + (.114-.114*U+.292*W)*in.b;
  ret.b = (.299-.3*U+1.25*W)*in.r
    + (.587-.588*U-1.05*W)*in.g
    + (.114+.886*U-.203*W)*in.b;
  return ret;
}

저는 제가 여기서 발견한 대부분의 답에 실망했습니다. 일부는 결함이 있었고 기본적으로 완전히 틀렸습니다.저는 결국 이것을 알아내려고 3시간 이상을 보냈습니다.마크 랜섬의 답변은 맞지만, 저는 MATLAB에서도 검증된 완전한 C 솔루션을 제공하고 싶습니다.저는 이것을 철저히 테스트했고, 다음은 C 코드입니다.

#include <math.h>
typedef unsigned char BYTE; //define an "integer" that only stores 0-255 value

typedef struct _CRGB //Define a struct to store the 3 color values
{
    BYTE r;
    BYTE g;
    BYTE b;
}CRGB;

BYTE clamp(float v) //define a function to bound and round the input float value to 0-255
{
    if (v < 0)
        return 0;
    if (v > 255)
        return 255;
    return (BYTE)v;
}

CRGB TransformH(const CRGB &in, const float fHue)
{
    CRGB out;
    const float cosA = cos(fHue*3.14159265f/180); //convert degrees to radians
    const float sinA = sin(fHue*3.14159265f/180); //convert degrees to radians
    //calculate the rotation matrix, only depends on Hue
    float matrix[3][3] = {{cosA + (1.0f - cosA) / 3.0f, 1.0f/3.0f * (1.0f - cosA) - sqrtf(1.0f/3.0f) * sinA, 1.0f/3.0f * (1.0f - cosA) + sqrtf(1.0f/3.0f) * sinA},
        {1.0f/3.0f * (1.0f - cosA) + sqrtf(1.0f/3.0f) * sinA, cosA + 1.0f/3.0f*(1.0f - cosA), 1.0f/3.0f * (1.0f - cosA) - sqrtf(1.0f/3.0f) * sinA},
        {1.0f/3.0f * (1.0f - cosA) - sqrtf(1.0f/3.0f) * sinA, 1.0f/3.0f * (1.0f - cosA) + sqrtf(1.0f/3.0f) * sinA, cosA + 1.0f/3.0f * (1.0f - cosA)}};
    //Use the rotation matrix to convert the RGB directly
    out.r = clamp(in.r*matrix[0][0] + in.g*matrix[0][1] + in.b*matrix[0][2]);
    out.g = clamp(in.r*matrix[1][0] + in.g*matrix[1][1] + in.b*matrix[1][2]);
    out.b = clamp(in.r*matrix[2][0] + in.g*matrix[2][1] + in.b*matrix[2][2]);
    return out;
}

참고: 회전 매트릭스는 색상(fHue), 일단 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , .matrix[3][3]동일한 색상 변환을 수행하는 이미지의 모든 픽셀에 대해 재사용할 수 있습니다!이렇게 하면 효율성이 크게 향상됩니다.다음은 결과를 확인하는 MATLAB 코드입니다.

function out = TransformH(r,g,b,H)
    cosA = cos(H * pi/180);
    sinA = sin(H * pi/180);

    matrix = [cosA + (1-cosA)/3, 1/3 * (1 - cosA) - sqrt(1/3) * sinA, 1/3 * (1 - cosA) + sqrt(1/3) * sinA;
          1/3 * (1 - cosA) + sqrt(1/3) * sinA, cosA + 1/3*(1 - cosA), 1/3 * (1 - cosA) - sqrt(1/3) * sinA;
          1/3 * (1 - cosA) - sqrt(1/3) * sinA, 1/3 * (1 - cosA) + sqrt(1/3) * sinA, cosA + 1/3 * (1 - cosA)];

    in = [r, g, b]';
    out = round(matrix*in);
end

다음은 두 코드로 재현 가능한 입력/출력 샘플입니다.

TransformH(86,52,30,210)
ans =
    36
    43
    88

그서입력는래 RGB는의 .[86,52,30] 변환되었습니다.[36,43,88]의 색조를 사용하여210.

Javascript 구현(위 Vladimir의 PHP 기반)

const deg = Math.PI / 180;

function rotateRGBHue(r, g, b, hue) {
  const cosA = Math.cos(hue * deg);
  const sinA = Math.sin(hue * deg);
  const neo = [
    cosA + (1 - cosA) / 3,
    (1 - cosA) / 3 - Math.sqrt(1 / 3) * sinA,
    (1 - cosA) / 3 + Math.sqrt(1 / 3) * sinA,
  ];
  const result = [
    r * neo[0] + g * neo[1] + b * neo[2],
    r * neo[2] + g * neo[0] + b * neo[1],
    r * neo[1] + g * neo[2] + b * neo[0],
  ];
  return result.map(x => uint8(x));
}

function uint8(value) {
  return 0 > value ? 0 : (255 < value ? 255 : Math.round(value));
}

기본적으로 두 가지 옵션이 있습니다.

  1. RGB -> HSV 변환, 색상 변경, HSV 변환 -> RGB
  2. 선형 변환을 사용하여 직접 색상 변경

2를 구현하는 방법은 잘 모르겠지만 기본적으로 변환 매트릭스를 생성하고 이 매트릭스를 통해 이미지를 필터링해야 합니다.그러나 이렇게 하면 색상만 변경하는 대신 이미지의 색상이 다시 지정됩니다.이것이 괜찮으시다면, 이것은 선택사항이 될 수 있지만 그렇지 않다면 변환을 피할 수 없습니다.

편집

약간의 조사는 이것을 보여주며, 이것은 제 생각을 확인시켜줍니다.요약:정확한 결과가 필요한 경우 RGB에서 HSV로 변환하는 것이 좋습니다.선형 변환을 통해 원본 RGB 이미지를 수정해도 결과가 나오지만 이는 오히려 이미지에 색조를 부여합니다.차이는 다음과 같습니다.RGB에서 HSV로의 변환은 비선형인 반면 변환은 선형입니다.

게시물은 오래되었고 원래 포스터는 iOS 코드를 찾고 있었습니다. 하지만 저는 비주얼 베이직 코드 검색을 통해 이곳으로 보내졌습니다. 그래서 저와 같은 모든 사람들을 위해 마크의 코드를 vb.net 모듈로 변환했습니다.

Public Module HueAndTry    
    Public Function ClampIt(ByVal v As Double) As Integer    
        Return CInt(Math.Max(0F, Math.Min(v + 0.5, 255.0F)))    
    End Function    
    Public Function DegreesToRadians(ByVal degrees As Double) As Double    
        Return degrees * Math.PI / 180    
    End Function    
    Public Function RadiansToDegrees(ByVal radians As Double) As Double    
        Return radians * 180 / Math.PI    
    End Function    
    Public Sub HueConvert(ByRef rgb() As Integer, ByVal degrees As Double)
        Dim selfMatrix(,) As Double = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}
        Dim cosA As Double = Math.Cos(DegreesToRadians(degrees))
        Dim sinA As Double = Math.Sin(DegreesToRadians(degrees))
        Dim sqrtOneThirdTimesSin As Double = Math.Sqrt(1.0 / 3.0) * sinA
        Dim oneThirdTimesOneSubCos As Double = 1.0 / 3.0 * (1.0 - cosA)
        selfMatrix(0, 0) = cosA + (1.0 - cosA) / 3.0
        selfMatrix(0, 1) = oneThirdTimesOneSubCos - sqrtOneThirdTimesSin
        selfMatrix(0, 2) = oneThirdTimesOneSubCos + sqrtOneThirdTimesSin
        selfMatrix(1, 0) = selfMatrix(0, 2)
        selfMatrix(1, 1) = cosA + oneThirdTimesOneSubCos
        selfMatrix(1, 2) = selfMatrix(0, 1)
        selfMatrix(2, 0) = selfMatrix(0, 1)
        selfMatrix(2, 1) = selfMatrix(0, 2)
        selfMatrix(2, 2) = cosA + oneThirdTimesOneSubCos
        Dim rx As Double = rgb(0) * selfMatrix(0, 0) + rgb(1) * selfMatrix(0, 1) + rgb(2) * selfMatrix(0, 2)
        Dim gx As Double = rgb(0) * selfMatrix(1, 0) + rgb(1) * selfMatrix(1, 1) + rgb(2) * selfMatrix(1, 2)
        Dim bx As Double = rgb(0) * selfMatrix(2, 0) + rgb(1) * selfMatrix(2, 1) + rgb(2) * selfMatrix(2, 2)
        rgb(0) = ClampIt(rx)
        rgb(1) = ClampIt(gx)
        rgb(2) = ClampIt(bx)
    End Sub
End Module

일반적인 용어를 (긴) 변수에 넣었지만, 그렇지 않으면 간단한 변환입니다. 필요에 맞게 잘 작동합니다.

그런데, 저는 마크의 훌륭한 코드에 대한 찬성표를 남기려고 했지만, 저 자신이 그것을 볼 수 있도록 하기에는 충분한 표가 없었습니다(힌트, 힌트).

WebGL 버전:

vec3 hueShift(vec3 col, float shift){
    vec3 m = vec3(cos(shift), -sin(shift) * .57735, 0);
    m = vec3(m.xy, -m.y) + (1. - m.x) * .33333;
    return mat3(m, m.zxy, m.yzx) * col;
}

HSV로 전환하는 것이 가장 타당한 것 같습니다.Sass는 몇 가지 놀라운 색상 도우미를 제공합니다.루비로 되어 있지만 유용할 수도 있습니다.

http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html

스콧.. 정확히는 아니지만요이 알고리즘은 HSL/HSV와 동일하게 작동하지만 더 빠릅니다.또한 배열의 첫 번째 3개 요소에 회색에 대한 요인을 곱하기만 하면 루마를 추가/감소시킬 수 있습니다.

예...Rec709의 그레이스케일은 다음 값을 갖습니다 [GrayRedFactor_Rec709: R$ 0.212671 GrayGreenFactor_Rec709: R$ 0.715160 GrayBlueFactor_R$ 0.072169].

GreyFactor 통신원과 self.matrix[x][x]를 곱하면 포화도 Ex를 건드리지 않고 루마가 감소합니다.

def set_hue_rotation(self, degrees):
    cosA = cos(radians(degrees))
    sinA = sin(radians(degrees))
    self.matrix[0][0] = (cosA + (1.0 - cosA) / 3.0) * 0.212671
    self.matrix[0][1] = (1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA) * 0.715160
    self.matrix[0][2] = (1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA) * 0.072169
    self.matrix[1][0] = self.matrix[0][2] <---Not sure, if this is the right code, but i think you got the idea
    self.matrix[1][1] = self.matrix[0][0]
    self.matrix[1][2] = self.matrix[0][1]

그리고 그 반대도 사실입니다.만약 여러분이 곱을 나누면, 광도는 극적으로 증가합니다.

제가 테스트하고 있는 바로는, 물론 포화 상태가 필요하지 않은 한, 이 알고리즘은 HSL의 훌륭한 대체물이 될 수 있습니다.

이렇게 해 보십시오. 색상을 1도만 회전하고(이미지의 인식 감도를 동일하게 유지하면서 알고가 제대로 작동하도록 강제하기 위해) 이러한 요소를 곱합니다.

매개 변수화된 HLSL 픽셀 셰이더로 위에서 설명한 (감마 보정되지 않은) 색상 이동이 필요한 사람(WPF 애플리케이션을 위해 함께 통과하고 공유할 수도 있다고 생각했습니다):

    sampler2D implicitInput : register(s0);
    float factor : register(c0);

    float4 main(float2 uv : TEXCOORD) : COLOR
    {
            float4 color = tex2D(implicitInput, uv);

            float h = 360 * factor;          //Hue
            float s = 1;                     //Saturation
            float v = 1;                     //Value
            float M_PI = 3.14159265359;

            float vsu = v * s*cos(h*M_PI / 180);
            float vsw = v * s*sin(h*M_PI / 180);

            float4 result;
            result.r = (.299*v + .701*vsu + .168*vsw)*color.r
                            + (.587*v - .587*vsu + .330*vsw)*color.g
                            + (.114*v - .114*vsu - .497*vsw)*color.b;
            result.g = (.299*v - .299*vsu - .328*vsw)*color.r
                            + (.587*v + .413*vsu + .035*vsw)*color.g
                            + (.114*v - .114*vsu + .292*vsw)*color.b;
            result.b = (.299*v - .300*vsu + 1.25*vsw)*color.r
                            + (.587*v - .588*vsu - 1.05*vsw)*color.g
                            + (.114*v + .886*vsu - .203*vsw)*color.b;;
            result.a = color.a;

            return result;
    }

훌륭한 코드지만 self.matrix[2][0], self.matrix[2][1], self.matrix[2][1]를 사용하지 않으면 더 빠를 수 있는지 궁금합니다.

따라서 set_hue_rotation은 간단하게 다음과 같이 쓸 수 있습니다.

def set_hue_rotation(self, degrees):
    cosA = cos(radians(degrees))
    sinA = sin(radians(degrees))
    self.matrix[0][0] = cosA + (1.0 - cosA) / 3.0
    self.matrix[0][1] = 1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA
    self.matrix[0][2] = 1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA
    self.matrix[1][0] = self.matrix[0][2] <---Not sure, if this is the right code, but i think you got the idea
    self.matrix[1][1] = self.matrix[0][0]
    self.matrix[1][2] = self.matrix[0][1]

또한 Mark의 알고리즘은 더 정확한 결과를 산출합니다.

예를 들어 HSV 색 공간을 사용하여 색상을 180도로 회전하면 이미지에 붉은 색조가 나타날 수 있습니다.

그러나 Mark의 알고리즘에서는 영상이 제대로 회전합니다.예를 들어, 피부색(Hue = 17, Sat = 170, L = 160)은 PSP에서 144개 정도의 Hue를 갖는 파란색으로 올바르게 전환되고 이미지의 다른 모든 색상은 올바르게 회전합니다.

Hue는 다음 공식에 의해 정의된 빨강, 초록, 파랑 아크탄의 로그 함수에 불과하기 때문에 알고리즘은 의미가 있습니다.

Hue = arctan((logR-logG)/(logR-logG+2*LogB))

PHP 구현:

class Hue
{
    public function convert(int $r, int $g, int $b, int $hue)
    {
        $cosA = cos($hue * pi() / 180);
        $sinA = sin($hue * pi() / 180);

        $neo = [
            $cosA + (1 - $cosA) / 3,
            (1 - $cosA) / 3 - sqrt(1 / 3) * $sinA,
            (1 - $cosA) / 3 + sqrt(1 / 3) * $sinA,
        ];

        $result = [
            $r * $neo[0] + $g * $neo[1] + $b * $neo[2],
            $r * $neo[2] + $g * $neo[0] + $b * $neo[1],
            $r * $neo[1] + $g * $neo[2] + $b * $neo[0],
        ];

        return array_map([$this, 'crop'], $result);
    }

    private function crop(float $value)
    {
        return 0 > $value ? 0 : (255 < $value ? 255 : (int)round($value));
    }
}

glsl에서 가장 컴팩트한 버전은 다음과 같습니다.

vec3 hs(vec3 c, float s){
    vec3 m=vec3(cos(s),s=sin(s)*.5774,-s);
    return c*mat3(m+=(1.-m.x)/3.,m.zxy,m.yzx);
}

약간 변화하는 마스터가치와 포화도를 다시 추가하기 위한 HD의 답변은 다음과 같은 C/C++ 코드로 끝납니다.

#include <math.h>
typedef unsigned char uint8_t; //if no posix defs, remove if not needed

//if you use C not C++ this needs to be typedef ..
struct Color{
    uint8_t r;
    uint8_t g;
    uint8_t b;
};


uint8_t clamp(float v) //define a function to bound and round the input float value to 0-255
{
    if (v < 0)
        return 0;
    if (v > 255)
        return 255;
    return (uint8_t)v;
}

//compare http://beesbuzz.biz/code/16-hsv-color-transforms
Color change_hsv_c(
    const Color &in, 
    const float fHue,
    const float fSat,
    const float fVal
)
{
    Color out;
    const float cosA = fSat*cos(fHue*3.14159265f/180); //convert degrees to radians
    const float sinA = fSat*sin(fHue*3.14159265f/180); //convert degrees to radians

    //helpers for faster calc //first 2 could actually be precomputed
    const float aThird = 1.0f/3.0f;
    const float rootThird = sqrtf(aThird);
    const float oneMinusCosA = (1.0f - cosA);
    const float aThirdOfOneMinusCosA = aThird * oneMinusCosA;
    const float rootThirdTimesSinA =  rootThird * sinA;
    const float plus = aThirdOfOneMinusCosA +rootThirdTimesSinA;
    const float minus = aThirdOfOneMinusCosA -rootThirdTimesSinA;

    //calculate the rotation matrix
    float matrix[3][3] = {
        {   cosA + oneMinusCosA / 3.0f  , minus                         , plus                          },
        {   plus                        , cosA + aThirdOfOneMinusCosA   , minus                         },
        {   minus                       , plus                          , cosA + aThirdOfOneMinusCosA   }
    };
    //Use the rotation matrix to convert the RGB directly
    out.r = clamp((in.r*matrix[0][0] + in.g*matrix[0][1] + in.b*matrix[0][2])*fVal);
    out.g = clamp((in.r*matrix[1][0] + in.g*matrix[1][1] + in.b*matrix[1][2])*fVal);
    out.b = clamp((in.r*matrix[2][0] + in.g*matrix[2][1] + in.b*matrix[2][2])*fVal);
    return out;
}

언급URL : https://stackoverflow.com/questions/8507885/shift-hue-of-an-rgb-color

반응형