代码统一放到最后。
结果如下
2、色调(hue)混合模式
叶明大神的用色调混合模式降低某一色彩的饱和度的文章: http://zhuanlan.zhihu.com/yeming/19978302
主要步骤为,新建一个待降低饱和度的色彩的图层,反相,图层混合模式改为色相,图层不透明度改为50%以下。
除了色调模式外此外,单色图层单色图层还可以使用以下混合模式 http://zhuanlan.zhihu.com/yeming/19988663
- 正片叠底:给高光部分着色
- 滤色: 给阴影部分着色
- 柔光: 整体着色,但比正常模式柔和
色调混合模式使用混合色的色调、基色的饱和度和明度。
但是,,,,PS中的色调混合模式不完全是这样的。。。
这里有个别人实现的结果与PS做对比,可以发现PS中优化了不少! http://www.cplotts.com/2009/11/29/blend-modes-hue-saturation-color-and-luminosity-with-wpf-4-0/
本文仅从理论上简单做个理论验证。
使用的公式是
xb=x*opacity+(1-opacity)*xs; yb=y*opacity+(1-opacity)*ys;
也就是把一个颜色中的色调、饱和度当做一个二维向量根据不透明度加权求和。
这么一来,饱和度也是要变的!!(PS中也会变)应该是合成向量所示的饱和度再乘以基色的饱和度。(这个没实现。)
不透明度为0.5时的一组使用色调混合模式引起的色彩偏移如下图所示:
代码:
function [colorDiskRGBImage,X,Y]=lcColourDisk(r) % 生成色盘图像 %r: 色盘半径-0.5。即色盘直径为2r+1 %输出: %colorDiskRGBImage 色盘图像,为(2r+1)*(2r+1)大小的。 %X:与色盘图像大小一样,对应于色盘图像中每个像素的x坐标。 %Y::与色盘图像大小一样,对应于色盘图像中每个像素的y坐标。 if(nargin==0) r=400; end %生成坐标网格 x=-r:r; x=x/r;%归一化到区间[-1,1] y=x; [X,Y]=meshgrid(x,y); %生成hue theta=atan2(Y,X); theta(theta<0)=theta(theta<0)+2*pi; hue=theta/2/pi; %生成saturation saturation=sqrt(X.^2+Y.^2); saturation(saturation>1)=0;%将位于色盘外的部分设置成没有颜色 %生成value value=ones(size(X)); imHSV=cat(3,hue,saturation,value); colorDiskRGBImage=hsv2rgb(imHSV); if(nargout==0) colorDiskRGBImage=flipud(colorDiskRGBImage); %注意matlab中y轴方向朝下,与一般情况不同,所以要翻转一下y坐标。 imshow(colorDiskRGBImage); end end
function blendHue(hueToBlend,opacity,colorDisk,X,Y,NPoints) %绘制色调混合模式下的色彩偏移图像 %hueToBlend: 混合色色调,[0,1] %opacity: 混合色的不透明度 %colorDisk,X,Y 为lcColourDisk的输出 %NPoints: 基色的点数 d=size(colorDisk,1); r=floor(d/2); center=ceil(d/2); theta=hueToBlend*2*pi; thetas=linspace(0,2*pi,NPoints);%选N个点作为基色 % thetaDiff=thetas-theta; % thetaDiff(thetaDiff<0)=thetaDiff(thetaDiff<0)+2*pi; % thetaDiff(thetaDiff>pi)=thetaDiff(thetaDiff>pi)-2*pi; %保证角度在[-pi, pi]之间 % thetasBlended=theta+thetaDiff*(1-opacity); % factor=1; [x y]=theta2xy(theta,center,r); [xs ys]=theta2xy(thetas,center,r); xb=x*opacity+(1-opacity)*xs; yb=y*opacity+(1-opacity)*ys; imshow(colorDisk); hold on plot(x,y,'ok') %quiver(center,center,xh-center,yh-center,0,'k'); plot(xs,ys,'*k') plot(xb,yb,'pk'); quiver(xs,ys,xb-xs,yb-ys,0,'k'); legend('混合色','基色','结果色') t=['色调混合模式下混色结果:opcacity=' num2str(opacity)]; title(t) axis xy %设置坐标轴y方向从下到上!! end function [x,y]=theta2xy(theta,center,r) x=center+r*cos(theta); y=center+r*sin(theta); end
%hue混合模式绘图的入口程序 close all [colorDisk,X,Y]=lcColourDisk(400); hueToBlend=0; opacity=0.5; Npoints=21; blendHue(hueToBlend,opacity,colorDisk,X,Y,Npoints)