欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ColorBlend公式

程序员文章站 2022-03-24 20:41:52
...

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;}
 
相关标签: blend