포토샵은 두 이미지를 어떻게 혼합합니까? [닫은]


84

내 응용 프로그램에서 동일한 효과를 재현 할 수 있도록 Photoshop에서 두 이미지를 혼합하는 방법을 설명해 주시겠습니까?


3
이것은 일반적인 컴퓨팅 하드웨어 나 소프트웨어에 대한 질문 이 아닙니다 . 알고리즘, C ++ 및 이미지 처리에 관한 것입니다. 질문의이 유형은 명시 적으로 허용 하고 적극적으로 장려
파나지오티스 Kanavos

8 년 동안이 사이트에 대한 클릭을 유도 한 후 지금은 주제에서 벗어난 것으로 간주됩니까?
Nathan Moinvaziri

필요한 것은 적어도 3000 명의 담당자로부터 5 개의 가까운 투표입니다. 그것은이 질문에 오히려 명백 하지 SO의 사회의 주제 오프 간주
파나지오티스 Kanavos

추신 : 4 개의 반대표는 8 년이 될 수 있습니다. 누군가 지난주 마감 대기열에서 질문을 발견하여 마감을 결정했을 수 있습니다. 그래서 지금은 질문 이 너무 많아서 더 이상 질문에 적절한주의를 기울이기가 어렵습니다. 원래의 질문이 너무 편집의 약간이 필요하다고 편집 이력 쇼
파나지오티스 Kanavos을

아마도 개정 3 또는 이와 유사한 것으로 되 돌리면 리뷰어가이를 다시 열 가능성이 높아집니다. 현재 상태에서는이 질문을 "내가 Photoshop을 사용하는 방법"질문으로 착각하고 연구 노력을 보여주지 않는 것으로 기각하기 쉽습니다.
Adam Millerchip 19

답변:


210

Photoshop은 이미지 B의 해당 픽셀에 대해 이미지 A의 각 픽셀에 대해 혼합 작업을 수행하여 두 이미지를 함께 혼합합니다. 각 픽셀은 여러 채널로 구성된 색상입니다. RGB 픽셀로 작업한다고 가정하면 각 픽셀의 채널은 빨강, 녹색 및 파랑이됩니다. 두 픽셀을 혼합하기 위해 각각의 채널을 혼합합니다.

Photoshop에서 각 블렌드 모드에 대해 발생하는 블렌드 작업은 다음 매크로로 요약 할 수 있습니다.

#define ChannelBlend_Normal(A,B)     ((uint8)(A))
#define ChannelBlend_Lighten(A,B)    ((uint8)((B > A) ? B:A))
#define ChannelBlend_Darken(A,B)     ((uint8)((B > A) ? A:B))
#define ChannelBlend_Multiply(A,B)   ((uint8)((A * B) / 255))
#define ChannelBlend_Average(A,B)    ((uint8)((A + B) / 2))
#define ChannelBlend_Add(A,B)        ((uint8)(min(255, (A + B))))
#define ChannelBlend_Subtract(A,B)   ((uint8)((A + B < 255) ? 0:(A + B - 255)))
#define ChannelBlend_Difference(A,B) ((uint8)(abs(A - B)))
#define ChannelBlend_Negation(A,B)   ((uint8)(255 - abs(255 - A - B)))
#define ChannelBlend_Screen(A,B)     ((uint8)(255 - (((255 - A) * (255 - B)) >> 8)))
#define ChannelBlend_Exclusion(A,B)  ((uint8)(A + B - 2 * A * B / 255))
#define ChannelBlend_Overlay(A,B)    ((uint8)((B < 128) ? (2 * A * B / 255):(255 - 2 * (255 - A) * (255 - B) / 255)))
#define ChannelBlend_SoftLight(A,B)  ((uint8)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255))))
#define ChannelBlend_HardLight(A,B)  (ChannelBlend_Overlay(B,A))
#define ChannelBlend_ColorDodge(A,B) ((uint8)((B == 255) ? B:min(255, ((A << 8 ) / (255 - B)))))
#define ChannelBlend_ColorBurn(A,B)  ((uint8)((B == 0) ? B:max(0, (255 - ((255 - A) << 8 ) / B))))
#define ChannelBlend_LinearDodge(A,B)(ChannelBlend_Add(A,B))
#define ChannelBlend_LinearBurn(A,B) (ChannelBlend_Subtract(A,B))
#define ChannelBlend_LinearLight(A,B)((uint8)(B < 128)?ChannelBlend_LinearBurn(A,(2 * B)):ChannelBlend_LinearDodge(A,(2 * (B - 128))))
#define ChannelBlend_VividLight(A,B) ((uint8)(B < 128)?ChannelBlend_ColorBurn(A,(2 * B)):ChannelBlend_ColorDodge(A,(2 * (B - 128))))
#define ChannelBlend_PinLight(A,B)   ((uint8)(B < 128)?ChannelBlend_Darken(A,(2 * B)):ChannelBlend_Lighten(A,(2 * (B - 128))))
#define ChannelBlend_HardMix(A,B)    ((uint8)((ChannelBlend_VividLight(A,B) < 128) ? 0:255))
#define ChannelBlend_Reflect(A,B)    ((uint8)((B == 255) ? B:min(255, (A * A / (255 - B)))))
#define ChannelBlend_Glow(A,B)       (ChannelBlend_Reflect(B,A))
#define ChannelBlend_Phoenix(A,B)    ((uint8)(min(A,B) - max(A,B) + 255))
#define ChannelBlend_Alpha(A,B,O)    ((uint8)(O * A + (1 - O) * B))
#define ChannelBlend_AlphaF(A,B,F,O) (ChannelBlend_Alpha(F(A,B),A,O))

단일 RGB 픽셀을 혼합하려면 다음을 수행합니다.

ImageTColorR = ChannelBlend_Glow(ImageAColorR, ImageBColorR); 
ImageTColorB = ChannelBlend_Glow(ImageAColorB, ImageBColorB);
ImageTColorG = ChannelBlend_Glow(ImageAColorG, ImageBColorG);

ImageTColor = RGB(ImageTColorR, ImageTColorB, ImageTColorG);

특정 불투명도로 블렌드 작업을 수행하려면 50 %라고합니다.

ImageTColorR = ChannelBlend_AlphaF(ImageAColorR, ImageBColorR, Blend_Subtract, 0.5F);

이미지 A, B 및 T (대상)에 대한 이미지 데이터에 대한 포인터가있는 경우 다음 매크로를 사용하여 세 채널 모두의 혼합을 단순화 할 수 있습니다.

#define ColorBlend_Buffer(T,A,B,M)      (T)[0] = ChannelBlend_##M((A)[0], (B)[0]),
                                        (T)[1] = ChannelBlend_##M((A)[1], (B)[1]),
                                        (T)[2] = ChannelBlend_##M((A)[2], (B)[2])

다음 RGB 색상 혼합 매크로를 파생 할 수 있습니다.

#define ColorBlend_Normal(T,A,B)        (ColorBlend_Buffer(T,A,B,Normal))
#define ColorBlend_Lighten(T,A,B)       (ColorBlend_Buffer(T,A,B,Lighten))
#define ColorBlend_Darken(T,A,B)        (ColorBlend_Buffer(T,A,B,Darken))
#define ColorBlend_Multiply(T,A,B)      (ColorBlend_Buffer(T,A,B,Multiply))
#define ColorBlend_Average(T,A,B)       (ColorBlend_Buffer(T,A,B,Average))
#define ColorBlend_Add(T,A,B)           (ColorBlend_Buffer(T,A,B,Add))
#define ColorBlend_Subtract(T,A,B)      (ColorBlend_Buffer(T,A,B,Subtract))
#define ColorBlend_Difference(T,A,B)    (ColorBlend_Buffer(T,A,B,Difference))
#define ColorBlend_Negation(T,A,B)      (ColorBlend_Buffer(T,A,B,Negation))
#define ColorBlend_Screen(T,A,B)        (ColorBlend_Buffer(T,A,B,Screen))
#define ColorBlend_Exclusion(T,A,B)     (ColorBlend_Buffer(T,A,B,Exclusion))
#define ColorBlend_Overlay(T,A,B)       (ColorBlend_Buffer(T,A,B,Overlay))
#define ColorBlend_SoftLight(T,A,B)     (ColorBlend_Buffer(T,A,B,SoftLight))
#define ColorBlend_HardLight(T,A,B)     (ColorBlend_Buffer(T,A,B,HardLight))
#define ColorBlend_ColorDodge(T,A,B)    (ColorBlend_Buffer(T,A,B,ColorDodge))
#define ColorBlend_ColorBurn(T,A,B)     (ColorBlend_Buffer(T,A,B,ColorBurn))
#define ColorBlend_LinearDodge(T,A,B)   (ColorBlend_Buffer(T,A,B,LinearDodge))
#define ColorBlend_LinearBurn(T,A,B)    (ColorBlend_Buffer(T,A,B,LinearBurn))
#define ColorBlend_LinearLight(T,A,B)   (ColorBlend_Buffer(T,A,B,LinearLight))
#define ColorBlend_VividLight(T,A,B)    (ColorBlend_Buffer(T,A,B,VividLight))
#define ColorBlend_PinLight(T,A,B)      (ColorBlend_Buffer(T,A,B,PinLight))
#define ColorBlend_HardMix(T,A,B)       (ColorBlend_Buffer(T,A,B,HardMix))
#define ColorBlend_Reflect(T,A,B)       (ColorBlend_Buffer(T,A,B,Reflect))
#define ColorBlend_Glow(T,A,B)          (ColorBlend_Buffer(T,A,B,Glow))
#define ColorBlend_Phoenix(T,A,B)       (ColorBlend_Buffer(T,A,B,Phoenix))

그리고 예는 다음과 같습니다.

ColorBlend_Glow(TargetPtr, ImageAPtr, ImageBPtr);

나머지 포토샵 블렌드 모드에는 RGB를 HLS로 변환 한 후 다시 변환하는 작업이 포함됩니다.

#define ColorBlend_Hue(T,A,B)            ColorBlend_Hls(T,A,B,HueB,LuminationA,SaturationA)
#define ColorBlend_Saturation(T,A,B)     ColorBlend_Hls(T,A,B,HueA,LuminationA,SaturationB)
#define ColorBlend_Color(T,A,B)          ColorBlend_Hls(T,A,B,HueB,LuminationA,SaturationB)
#define ColorBlend_Luminosity(T,A,B)     ColorBlend_Hls(T,A,B,HueA,LuminationB,SaturationA)

#define ColorBlend_Hls(T,A,B,O1,O2,O3) {
    float64 HueA, LuminationA, SaturationA;
    float64 HueB, LuminationB, SaturationL;
    Color_RgbToHls((A)[2],(A)[1],(A)[0], &HueA, &LuminationA, &SaturationA);
    Color_RgbToHls((B)[2],(B)[1],(B)[0], &HueB, &LuminationB, &SaturationB);
    Color_HlsToRgb(O1,O2,O3,&(T)[2],&(T)[1],&(T)[0]);
    }

이 함수는 RGB를 HLS로 변환하는 데 유용합니다.

int32 Color_HueToRgb(float64 M1, float64 M2, float64 Hue, float64 *Channel)
{
    if (Hue < 0.0)
        Hue += 1.0;
    else if (Hue > 1.0)
        Hue -= 1.0;

    if ((6.0 * Hue) < 1.0)
        *Channel = (M1 + (M2 - M1) * Hue * 6.0);
    else if ((2.0 * Hue) < 1.0)
        *Channel = (M2);
    else if ((3.0 * Hue) < 2.0)
        *Channel = (M1 + (M2 - M1) * ((2.0F / 3.0F) - Hue) * 6.0);
    else
        *Channel = (M1);

    return TRUE;
}

int32 Color_RgbToHls(uint8 Red, uint8 Green, uint8 Blue, float64 *Hue, float64 *Lumination, float64 *Saturation)
{
    float64 Delta;
    float64 Max, Min;
    float64 Redf, Greenf, Bluef;

    Redf    = ((float64)Red   / 255.0F);
    Greenf  = ((float64)Green / 255.0F);
    Bluef   = ((float64)Blue  / 255.0F); 

    Max     = max(max(Redf, Greenf), Bluef);
    Min     = min(min(Redf, Greenf), Bluef);

    *Hue        = 0;
    *Lumination = (Max + Min) / 2.0F;
    *Saturation = 0;

    if (Max == Min)
        return TRUE;

    Delta = (Max - Min);

    if (*Lumination < 0.5)
        *Saturation = Delta / (Max + Min);
    else
        *Saturation = Delta / (2.0 - Max - Min);

    if (Redf == Max)
        *Hue = (Greenf - Bluef) / Delta;
    else if (Greenf == Max)
        *Hue = 2.0 + (Bluef - Redf) / Delta;
    else
        *Hue = 4.0 + (Redf - Greenf) / Delta;

    *Hue /= 6.0; 

    if (*Hue < 0.0)
        *Hue += 1.0;       

    return TRUE;
}

int32 Color_HlsToRgb(float64 Hue, float64 Lumination, float64 Saturation, uint8 *Red, uint8 *Green, uint8 *Blue)
{
    float64 M1, M2;
    float64 Redf, Greenf, Bluef;

    if (Saturation == 0)
        {
        Redf    = Lumination;
        Greenf  = Lumination;
        Bluef   = Lumination;
        }
    else
        {
        if (Lumination <= 0.5)
            M2 = Lumination * (1.0 + Saturation);
        else
            M2 = Lumination + Saturation - Lumination * Saturation;

        M1 = (2.0 * Lumination - M2);

        Color_HueToRgb(M1, M2, Hue + (1.0F / 3.0F), &Redf);
        Color_HueToRgb(M1, M2, Hue, &Greenf);
        Color_HueToRgb(M1, M2, Hue - (1.0F / 3.0F), &Bluef);
        }

    *Red    = (uint8)(Redf * 255);
    *Blue   = (uint8)(Bluef * 255);
    *Green  = (uint8)(Greenf * 255);

    return TRUE;
}

이 주제에 대한 더 많은 리소스는 주로 다음과 같습니다.

  1. PegTop 블렌드 모드
  2. 법의학 포토샵
  3. Photoshop 7.0 혼합 모드에 대한 통찰력
  4. SF-기본-혼합 모드
  5. 블렌드 모드 완료
  6. Romz 블로그
  7. ReactOS RGB-HLS 변환 기능

1
예, 좋은 답변입니다. 감사합니다! 누군가가 포토샵에서 레이어 불투명도를 수행하는 방법을 알고 있는지 궁금합니다. 즉, 블렌드 어둡게 기능을 사용하고 싶지만 50 % 만 ... 포토샵에서 값을 확인
했는데

2
주어진 알파 공식은 완전하지 않습니다. 배경이 완전히 불투명 한 경우에만 작동합니다. 배경이 투명하면 그리기 후 결과가 투명해질 수 있습니다. 더 일반적인 경우에는 Wikipedia설명 된 것과 같은 알파 블렌딩을 적용해야합니다 .
thenickdude

2
알파 채널은 어떻습니까? 기능도 적용해야하나요?
akhy

좋은 대답 !! 반사글로우 가 전환됩니다. 그렇지 않으면 : 좋습니다 !! (알파 합성이 누락되었지만 ..)
TaW

알파 합성을위한 c # 솔루션 : static Color alphaComposite (Color c1, Color c2, Color cb, float op) {float a1, a2, ab, ar = 1; ar = v [c1.A] + v [c2.A] * op-(v [c1.A] * v [c2.A] * op); float asr = v [c2.A] * op / ar; a1 = 1-asr; a2 = asr * (1-v [c1.A]); ab = asr * v [c1.A]; 바이트 r = (바이트) (c1.R * a1 + c2.R * a2 + cb.R * ab); 바이트 g = (바이트) (c1.G * a1 + c2.G * a2 + cb.G * ab); 바이트 b = (바이트) (c1.B * a1 + c2.B * a2 + cb.B * ab); return Color.FromArgb ((byte) (ar * 255), r, g, b); }
TaW

7

이 답변의 색조, 색상, 채도 혼합 모드가 잘못되었습니다. Adobe 제품은 HSB로 변환되지 않으며 RGB 값에서 직접 작업을 수행합니다.

다음은 광도 설정을위한 GLSL입니다. 예를 들면 다음과 같습니다.

float lum(vec4 color)
{
    return ((0.3 * color.r) + (0.59 * color.g) + (0.11 * color.b));
}

vec4 clipColor(vec4 color)
{
    vec4 newColor=color;
    float l=lum(color);
    float n=min(min(color.r,color.g),color.b);
    float x=max(max(color.r,color.g),color.b);

    newColor.r=(n<0.0) ? l+(((color.r-l)*l)/(l-n)) : color.r;
    newColor.r=(x>1.0) ? l+(((color.r-l)*(1.0-l))/(x-l)) : color.r;

    newColor.g=(n<0.0) ? l+(((color.g-l)*l)/(l-n)) : color.g;
    newColor.g=(x>1.0) ? l+(((color.g-l)*(1.0-l))/(x-l)) : color.g;

    newColor.b=(n<0.0) ? l+(((color.b-l)*l)/(l-n)) : color.b;
    newColor.b=(x>1.0) ? l+(((color.b-l)*(1.0-l))/(x-l)) : color.b;

    return clamp(newColor,0.0,1.0);
}

vec4 setlum(vec4 color, float l)
{
    float d=l-lum(color);
    color.r+=d;
    color.g+=d;
    color.b+=d;

    return clipColor(color);    
}

kernel vec4 blendLuminosity(sampler topimage, sampler bottomimage)
{
    vec4 base=sample(bottomimage, samplerCoord(bottomimage));
    vec4 blend=sample(topimage, samplerCoord(topimage));

    float bl=lum(blend);
    return setlum(base,bl);
}

CIKernels에서 if .. else 문을 지원하지 않으므로 삼항 연산자를 사용합니다.


4

인기있는 답변은 99.9 % 정확하지만 Greyfriars가 말했듯이 Adobe는 블렌딩에서 HLS를 사용하지 않기 때문에 정확한 결과를 얻지 못할 것입니다.

하지만 그렇게하기 위해 Adobe에서 일할 필요는 없습니다. Adobe의이 문서에있는 모든 규칙에 따라 정확히 동일한 블렌딩에 도달 할 수 있습니다.

기본적으로 4 장 및 7 장 : http://partners.adobe.com/public/developer/en/pdf/PDFReference.pdf

그러면 Adobe처럼 정확한 결과를 얻을 수 있습니다! Pixel by Pixel!


i.imgur.com/G5MbHOH.png 링크에 HSL이 사용되었다고 표시됩니다 (링크가 끊어 졌기 때문에 여기를 따랐습니다 : adobe.com/content/dam/acom/en/devnet/pdf/pdfs/… )
eri0o

0

대중적인 대답은 대부분 정확하지만 다음 진술은 잘못되었습니다. "나머지 포토샵 블렌드 모드는 RGB를 HLS로 변환하고 다시 되 돌리는 작업을 포함합니다." 아니요, Photoshop (및 Photoshop 만 해당)은 HLS 대신 Chroma 및 Luma를 사용합니다.

따라서 Hue, Color, Luminosity 및 Saturation 모드의 경우 간단한 알고리즘을 사용할 수 없습니다. 이러한 경우 Photoshop의 방법과 일치하려면 Adobe에서 작업해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.