Làm thế nào để photoshop ghép hai hình ảnh lại với nhau? [đóng cửa]


84

Ai đó có thể vui lòng giải thích cách Photoshop kết hợp hai hình ảnh với nhau để tôi có thể tạo lại các hiệu ứng giống nhau trong ứng dụng của mình không.


3
Đây chắc chắn không phải là một câu hỏi về phần cứng hoặc phần mềm máy tính nói chung. Đó là về thuật toán, C ++ và xử lý hình ảnh. Đây là loại câu hỏi được phép một cách rõ ràngtích cực khuyến khích
Panagiotis Kanavos

Sau 8 năm thúc đẩy lượt nhấp chuột vào trang web này, giờ nó chỉ bị coi là lạc đề?
Nathan Moinvaziri

Tất cả những gì nó cần là 5 phiếu bầu sát sao từ những người có ít nhất 3000 đại diện. Đó là khá rõ ràng câu hỏi này được không coi off-topic của cộng đồng SO
Panagiotis Kanavos

Tái bút: 4 phiếu phản đối có thể là 8 năm tuổi. Ai đó có thể đã gặp câu hỏi trong hàng đợi đóng vào tuần trước và đã bỏ phiếu để đóng. Hiện tại có quá nhiều câu hỏi nên thật khó để chú ý đến câu hỏi nào nữa. Các chương trình chỉnh sửa lịch sử mà câu hỏi ban đầu cần một chút chỉnh sửa quá
Panagiotis Kanavos

Có lẽ việc hoàn nguyên về bản sửa đổi 3, hoặc điều gì đó tương tự, sẽ khiến điều này có nhiều khả năng được người đánh giá mở lại. Ở trạng thái hiện tại, rất dễ nhầm câu hỏi là câu hỏi "làm cách nào để sử dụng Photoshop" và cũng có thể loại bỏ nó vì nó không cho thấy bất kỳ nỗ lực nghiên cứu nào.
Adam Millerchip

Câu trả lời:


210

Photoshop trộn hai hình ảnh với nhau bằng cách thực hiện thao tác trộn trên mỗi pixel trong hình ảnh A với pixel tương ứng của nó trong hình ảnh B. Mỗi pixel là một màu bao gồm nhiều kênh. Giả sử chúng ta đang làm việc với các pixel RGB, các kênh trong mỗi pixel sẽ có màu đỏ, xanh lục và xanh lam. Để trộn hai pixel, chúng tôi trộn các kênh tương ứng của chúng.

Hoạt động hòa trộn xảy ra cho mỗi chế độ hòa trộn trong Photoshop có thể được tóm tắt trong các macro sau:

#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))

Để pha trộn một pixel RGB duy nhất, bạn sẽ làm như sau:

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

ImageTColor = RGB(ImageTColorR, ImageTColorB, ImageTColorG);

Nếu chúng tôi muốn thực hiện thao tác trộn với độ mờ cụ thể, hãy nói 50%:

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

Nếu bạn có con trỏ đến dữ liệu hình ảnh cho hình ảnh A, B và T (mục tiêu của chúng tôi), chúng tôi có thể đơn giản hóa việc kết hợp cả ba kênh bằng cách sử dụng macro này:

#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])

Và có thể lấy các macro pha trộn màu RGB sau:

#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))

Và ví dụ sẽ là:

ColorBlend_Glow(TargetPtr, ImageAPtr, ImageBPtr);

Phần còn lại của các chế độ hòa trộn trong photoshop liên quan đến việc chuyển đổi RGB sang HLS và quay lại một lần nữa.

#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]);
    }

Các chức năng này sẽ hữu ích trong việc chuyển đổi RGB sang 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;
}

Có nhiều tài nguyên hơn về chủ đề này, chủ yếu là:

  1. Chế độ hòa trộn PegTop
  2. Photoshop pháp y
  3. Tìm hiểu sâu về các chế độ hòa trộn của Photoshop 7.0
  4. SF - Khái niệm cơ bản - Chế độ kết hợp
  5. hoàn thành các chế độ hòa trộn
  6. Blog của Romz
  7. Các chức năng chuyển đổi ReactOS RGB-HLS

1
vâng, câu trả lời tuyệt vời, cảm ơn! Tôi đã tự hỏi nếu ai đó biết làm thế nào độ mờ của lớp được thực hiện trong photoshop? tức là tôi muốn sử dụng chức năng làm tối pha trộn nhưng chỉ có 50% ... Tôi đã kiểm tra các giá trị trong photoshop và có vẻ như không, rằng nó đủ để chỉ lấy 50% giá trị của hình ảnh pha trộn ...
Maecky

2
Công thức alpha được đưa ra không hoàn chỉnh - nó chỉ hoạt động trong trường hợp nền hoàn toàn không trong suốt. Nếu nền trong suốt, kết quả sau khi vẽ có thể trong suốt. Bạn cần áp dụng cách trộn alpha như được mô tả trên Wikipedia cho trường hợp tổng quát hơn đó.
thenickdude

2
Làm thế nào về kênh alpha? Tôi có nên áp dụng các chức năng cho nó không?
akhy

Câu trả lời chính xác!! Phản ánh và Phát sáng được chuyển đổi. Nếu không: Tuyệt vời !! (Mặc dù thiếu kết hợp alpha ..)
TaW

c # giải pháp cho alpha-comp'ing: static Color alphaComposite (Màu c1, Màu c2, Màu 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]; byte r = (byte) (c1.R * a1 + c2.R * a2 + cb.R * ab); byte g = (byte) (c1.G * a1 + c2.G * a2 + cb.G * ab); byte b = (byte) (c1.B * a1 + c2.B * a2 + cb.B * ab); return Color.FromArgb ((byte) (ar * 255), r, g, b); }
TaW

7

Các chế độ hòa trộn Hue, Color, Saturation trong câu trả lời này là sai. Không có sản phẩm Adobe nào chuyển đổi sang HSB, chúng thực hiện thao tác trực tiếp trên các giá trị RGB.

Đây là GLSL để thiết lập độ sáng, ví dụ:

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);
}

Không hỗ trợ các câu lệnh if .. else trong CIKernels, do đó việc sử dụng các toán tử bậc ba.


4

Câu trả lời phổ biến là đúng 99,9%, nhưng như Greyfriars đã nói, nó sẽ không nhận được kết quả chính xác vì Adobe không sử dụng HLS bất kỳ lúc nào trong quá trình hòa trộn.

Nhưng bạn không cần phải làm việc tại Adobe để làm điều đó ... bạn có thể đạt được sự kết hợp chính xác theo tất cả các quy tắc ở đây trong tài liệu này từ Adobe:

về cơ bản chương 4 và 7: http://partners.adobe.com/public/developer/en/pdf/PDFReference.pdf

Sau đó, bạn sẽ đạt được kết quả chính xác giống như Adobe làm! Pixel by Pixel!


i.imgur.com/G5MbHOH.png nó cho biết HSL được sử dụng trong liên kết (Tôi theo dõi ở đây vì liên kết đó đã bị hỏng đối với tôi: adobe.com/content/dam/acom/vi/devnet/pdf/pdfs/… )
eri0o 23/09/18

0

Trong khi câu trả lời phổ biến hầu hết là đúng, câu sau đây là sai. "Phần còn lại của các chế độ hòa trộn trong photoshop liên quan đến việc chuyển đổi RGB sang HLS và quay lại một lần nữa." Không, Photoshop (và chỉ Photoshop) sử dụng Chroma và Luma thay vì HLS.

Vì vậy, đối với các chế độ Hue, Color, Luminosity và Saturation, bạn không thể sử dụng các thuật toán đơn giản. Để phù hợp với phương pháp của Photoshop trong những trường hợp này, bạn cần phải làm việc cho Adobe.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.