The blend operation that occurs for each blend mode in Photoshop can be summed up in the following macros:
#defineChannelBlend_Normal(A,B)((uint8)(A))#defineChannelBlend_Lighten(A,B)((uint8)((B > A)? B:A))#defineChannelBlend_Darken(A,B)((uint8)((B > A)? A:B))#defineChannelBlend_Multiply(A,B)((uint8)((A * B)/255))#defineChannelBlend_Average(A,B)((uint8)((A + B)/2))#defineChannelBlend_Add(A,B)((uint8)(min(255,(A + B))))#defineChannelBlend_Subtract(A,B)((uint8)((A + B <255)?0:(A + B -255)))#defineChannelBlend_Difference(A,B)((uint8)(abs(A - B)))#defineChannelBlend_Negation(A,B)((uint8)(255- abs(255- A - B)))#defineChannelBlend_Screen(A,B)((uint8)(255-(((255- A)*(255- B))>>8)))#defineChannelBlend_Exclusion(A,B)((uint8)(A + B -2* A * B /255))#defineChannelBlend_Overlay(A,B)((uint8)((B <128)?(2* A * B /255):(255-2*(255- A)*(255- B)/255)))#defineChannelBlend_SoftLight(A,B)((uint8)((B <128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255))))#defineChannelBlend_HardLight(A,B)(ChannelBlend_Overlay(B,A))#defineChannelBlend_ColorDodge(A,B)((uint8)((B ==255)? B:min(255,((A <<8)/(255- B)))))#defineChannelBlend_ColorBurn(A,B)((uint8)((B ==0)? B:max(0,(255-((255- A)<<8)/ B))))#defineChannelBlend_LinearDodge(A,B)(ChannelBlend_Add(A,B))#defineChannelBlend_LinearBurn(A,B)(ChannelBlend_Subtract(A,B))#defineChannelBlend_LinearLight(A,B)((uint8)(B <128)?ChannelBlend_LinearBurn(A,(2* B)):ChannelBlend_LinearDodge(A,(2*(B -128))))#defineChannelBlend_VividLight(A,B)((uint8)(B <128)?ChannelBlend_ColorBurn(A,(2* B)):ChannelBlend_ColorDodge(A,(2*(B -128))))#defineChannelBlend_PinLight(A,B)((uint8)(B <128)?ChannelBlend_Darken(A,(2* B)):ChannelBlend_Lighten(A,(2*(B -128))))#defineChannelBlend_HardMix(A,B)((uint8)((ChannelBlend_VividLight(A,B)<128)?0:255))#defineChannelBlend_Reflect(A,B)((uint8)((B ==255)? B:min(255,(A * A /(255- B)))))#defineChannelBlend_Glow(A,B)(ChannelBlend_Reflect(B,A))#defineChannelBlend_Phoenix(A,B)((uint8)(min(A,B)- max(A,B)+255))#defineChannelBlend_Alpha(A,B,O)((uint8)(O * A +(1- O)* B))#defineChannelBlend_AlphaF(A,B,F,O)(ChannelBlend_Alpha(F(A,B),A,O))
To blend a single RGB pixel you would do the following:
ImageTColorR=ChannelBlend_Glow(ImageAColorR,ImageBColorR);ImageTColorB=ChannelBlend_Glow(ImageAColorB,ImageBColorB);ImageTColorG=ChannelBlend_Glow(ImageAColorG,ImageBColorG);ImageTColor= RGB(ImageTColorR,ImageTColorB,ImageTColorG);
If we wanted to perform a blend operation with a particular opacity, say 50%:
ImageTColorR=ChannelBlend_AlphaF(ImageAColorR,ImageBColorR,Blend_Subtract,0.5F);
If you have pointers to the image data for images A, B, and T (our target), we can simplify the blending of all three channels using this macro:
#defineColorBlend_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])
And can derive the following RGB color blend macros:
#defineColorBlend_Normal(T,A,B)(ColorBlend_Buffer(T,A,B,Normal))#defineColorBlend_Lighten(T,A,B)(ColorBlend_Buffer(T,A,B,Lighten))#defineColorBlend_Darken(T,A,B)(ColorBlend_Buffer(T,A,B,Darken))#defineColorBlend_Multiply(T,A,B)(ColorBlend_Buffer(T,A,B,Multiply))#defineColorBlend_Average(T,A,B)(ColorBlend_Buffer(T,A,B,Average))#defineColorBlend_Add(T,A,B)(ColorBlend_Buffer(T,A,B,Add))#defineColorBlend_Subtract(T,A,B)(ColorBlend_Buffer(T,A,B,Subtract))#defineColorBlend_Difference(T,A,B)(ColorBlend_Buffer(T,A,B,Difference))#defineColorBlend_Negation(T,A,B)(ColorBlend_Buffer(T,A,B,Negation))#defineColorBlend_Screen(T,A,B)(ColorBlend_Buffer(T,A,B,Screen))#defineColorBlend_Exclusion(T,A,B)(ColorBlend_Buffer(T,A,B,Exclusion))#defineColorBlend_Overlay(T,A,B)(ColorBlend_Buffer(T,A,B,Overlay))#defineColorBlend_SoftLight(T,A,B)(ColorBlend_Buffer(T,A,B,SoftLight))#defineColorBlend_HardLight(T,A,B)(ColorBlend_Buffer(T,A,B,HardLight))#defineColorBlend_ColorDodge(T,A,B)(ColorBlend_Buffer(T,A,B,ColorDodge))#defineColorBlend_ColorBurn(T,A,B)(ColorBlend_Buffer(T,A,B,ColorBurn))#defineColorBlend_LinearDodge(T,A,B)(ColorBlend_Buffer(T,A,B,LinearDodge))#defineColorBlend_LinearBurn(T,A,B)(ColorBlend_Buffer(T,A,B,LinearBurn))#defineColorBlend_LinearLight(T,A,B)(ColorBlend_Buffer(T,A,B,LinearLight))#defineColorBlend_VividLight(T,A,B)(ColorBlend_Buffer(T,A,B,VividLight))#defineColorBlend_PinLight(T,A,B)(ColorBlend_Buffer(T,A,B,PinLight))#defineColorBlend_HardMix(T,A,B)(ColorBlend_Buffer(T,A,B,HardMix))#defineColorBlend_Reflect(T,A,B)(ColorBlend_Buffer(T,A,B,Reflect))#defineColorBlend_Glow(T,A,B)(ColorBlend_Buffer(T,A,B,Glow))#defineColorBlend_Phoenix(T,A,B)(ColorBlend_Buffer(T,A,B,Phoenix))
And example would be:
ColorBlend_Glow(TargetPtr,ImageAPtr,ImageBPtr);
The remainder of the photoshop blend modes involve converting RGB to HLS and back again.
#defineColorBlend_Hue(T,A,B)ColorBlend_Hls(T,A,B,HueB,LuminationA,SaturationA)#defineColorBlend_Saturation(T,A,B)ColorBlend_Hls(T,A,B,HueA,LuminationA,SaturationB)#defineColorBlend_Color(T,A,B)ColorBlend_Hls(T,A,B,HueB,LuminationA,SaturationB)#defineColorBlend_Luminosity(T,A,B)ColorBlend_Hls(T,A,B,HueA,LuminationB,SaturationA)#defineColorBlend_Hls(T,A,B,O1,O2,O3){float64HueA,LuminationA,SaturationA;float64HueB,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]);}
These functions will be helpful in converting RGB to HLS.
int32Color_HueToRgb(float64 M1,float64 M2,float64Hue,float64*Channel){if(Hue<0.0)Hue+=1.0;elseif(Hue>1.0)Hue-=1.0;if((6.0*Hue)<1.0)*Channel=(M1 +(M2 - M1)*Hue*6.0);elseif((2.0*Hue)<1.0)*Channel=(M2);elseif((3.0*Hue)<2.0)*Channel=(M1 +(M2 - M1)*((2.0F/3.0F)-Hue)*6.0);else*Channel=(M1);return TRUE;}int32Color_RgbToHls(uint8Red,uint8Green,uint8Blue,float64*Hue,float64*Lumination,float64*Saturation){float64Delta;float64Max,Min;float64Redf,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;elseif(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;}int32Color_HlsToRgb(float64Hue,float64Lumination,float64Saturation,uint8*Red,uint8*Green,uint8*Blue){float64 M1, M2;float64Redf,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;}
相关推荐
本节将深入探讨Alpha Blend的工作原理、实现方式以及与Color混合的关系。 首先,我们要理解Alpha通道。在RGBA模型中,每个像素都有四个分量:R(红色)、G(绿色)、B(蓝色)和A(阿尔法)。R、G、B分别控制像素的...
1. 计算源颜色(Source Color)和目的地颜色(Destination Color)的组合。 2. 应用一个可配置的混合函数来确定新颜色的每个分量。 3. 更新帧缓冲区中的颜色。 ### 阿尔法混合(Alpha Blending) 阿尔法混合是混合...
在压缩包文件"AlphaBlend"中,可能包含一个演示Alpha混合的Direct3D程序。此程序可能包括创建设备、加载纹理、设置混合状态、绘制几何体等步骤,并通过改变Alpha值展示不同的透明效果。通过分析和学习这个示例,...
在给定的“alphablend_demo.zip”压缩包中,包含了一系列的C++源代码文件,如AlphaBlending.cpp、AlphaBlend.cpp等,它们提供了一个用于图像处理的Alpha Blending演示DEMO,帮助我们理解并应用这一技术。 Alpha ...
包括Normal、Multiply、Screen、Overlay、Darken、Lighten、ColorDodge、ColorBurn、HighLight、SoftLight、Difference、Exclusion、Hue、Saturation、Color、Luminosity等的详细说明和具体公式。
- **Color Burn(颜色加深)**:与Color Dodge相反,上层像素的亮度决定下层的曝光,使下层变暗,公式为`C = 1 - (1 - B) / A`。 - **Linear Dodge(线形减淡)**:直接将像素值相加,使结果更亮,公式为`C = A + ...
unity image颜色混合shader,颜色...会一点shader的可以去搜颜色混合公式,改一改可以实现各种ps中的混合效果。具体混合颜色根据image的color属性混合,达到同一材质可以出现不同叠加颜色的效果,给初学者一点思路。
头发各向异性渲染Shader 这个是04年的一个ppt,主要介绍了头发的渲染,其追到源头还是要看这个原理。...Blend SrcAlpha OneMinusSrcAlpha ZWrite Off 注意第二个通道无需再进行clip操作。 至此,头发渲染完毕。
在OpenGL中,可以通过`glEnable(GL_BLEND)`开启混合功能,然后通过`glBlendFunc`设置混合函数。 3. **深度缓冲区**:为了正确处理透明物体与不透明物体的遮挡关系,我们需要使用深度缓冲区。深度缓冲区记录了每个...
std::cout << "Usage: ./ImageBlend [image1] [image2] [alpha]" ; return -1; } cv::Mat img1 = cv::imread(argv[1], cv::IMREAD_COLOR); cv::Mat img2 = cv::imread(argv[2], cv::IMREAD_COLOR); if (!img...
混合操作的核心是一个简单的线性组合公式。设源颜色为`(Rs, Gs, Bs, As)`,目标颜色为`(Rd, Gd, Bd, Ad)`,源因子为`(Sr, Sg, Sb, Sa)`,目标因子为`(Dr, Dg, Db, Da)`,则混合后的颜色可以表示为: \[ (R' = Rs \...
3. 结果像素的计算公式通常为:`ResultColor = BackgroundColor * (1 - Alpha) + ForegroundColor * Alpha`,其中Alpha范围在0到1之间。 4. 更新屏幕上的像素,以显示融合后的图像。 最后,`GID_BMP.exe`是一个可...
融合操作的具体计算公式为: ``` result = (source * sfactor) + (destination * dfactor) ``` 其中,source 和 destination 分别表示源颜色和目的颜色,sfactor 和 dfactor 分别为对应的因子。 **2.3 启动融合...
3. **遍历并修改像素**:对于指定范围内的每个像素,使用`getpixel()`获取其颜色值,然后根据公式`new_pixel = original_pixel * (1 - opacity) + overlay_color * opacity`计算新的颜色值,并使用`putpixel()`更新...