`
迷失的帆板
  • 浏览: 1379 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

ColorBlend公式

阅读更多

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;}
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics