photoshop图象/模式。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了photoshop图象/模式。相关的知识,希望对你有一定的参考价值。

ps 图象/模式里. 灰度, 索引. LAB .多通道。16位通道,18位通道。分别有什么作用. 在什么情况下用. 说的清楚,简洁点阿. 不要那种复制一大堆的。 谢谢。

这是我从书中看到的,希望对你有帮助。 组合混合模式 正常模式(Normal模式)——这是图层混合模式的默认方式,较为常用。不和其他图层发生任何混合。使用时用当前图层像素的颜色覆盖下层颜色。
因为在PhotoShop中颜色是当作光线处理的(而不是物理颜料),在Normal模式下形成的合成或着色作品中不会用到颜色的相减属性。例如,在Normal模式下,在100%不透明红色选择上面的50%不透明蓝色选择产生一种淡紫色,而不是混合物理颜料时所期望得上 到的深紫色。当增大蓝色选择的不透明度时,结果颜色变得更蓝而不太红,直到100%不透明度时蓝色变成了组合颜色的颜色。用Paintbrush I具以50%的不透明度把蓝色涂在红色区域上结果相同;在红色区域上描划得越多,就有更多的蓝色前景色变成区域内最终的颜色。于是,在Normal模式下,永远也不可能得到一种比混合的两种颜色成分中最暗的那个更暗的混合色了。

溶解模式(Dissolve模式)——溶解模式产生的像素颜色来源于上下混合颜色的一个随机置换值,与像素的不透明度有关。将目标层图像以散乱的点状形式叠加到底层图像上时,对图像的色彩不产生任何的影响。通过调节不透明度,可增加或减少目标层散点的密度。其结果通常是画面呈现颗粒状或线条边缘粗糙化。
Dissolve模式当定义为层的混合模式时,将产生不可须知的结果。因此,这个模式最好是同Photoshop中的着色应用程序工具一同使用。U1ssQlve模式采用100%不透明的前景色(或采样的像素,当与Rubber Stamp工具一起使用时),同底层的原始颜色交替以创建一种类似扩散抖动的效果。在Dissolve模式中通常采用的颜色或图像样本的不透明度越低,颜色 或祥本同原始图像像素散布的频率就越低。如果以小于或等于50%的不透明度描划一条路径,Dissolve模式在图像边缘周围创建一个条纹。这种效果对模拟破损纸的边缘或原图的“泼溅”类型是重要的。

变暗混合模式变暗模式(Darken模式)——该模式是混合两图层像素的颜色时,对这二者的RGB值(即RGB通道中的颜色亮度值)分别进行比较,取二者中低的值再组合成为混合后的颜色,所以总的颜色灰度级降低,造成变暗的效果。显然用白色去合成图像时毫无效果。考察每一个通道的颜色信息以及相混合的像素颜色,选择较暗的作为混合的结果。颜色较亮的像素会被颜色较暗的像素替换,而较暗的像素就不会发生变化。
在此模式下,仅采用了其层上颜色(或Darken模式中应用的着色)比背景颜色更暗的这些层上的色调。这种模式导致比背景颜色更淡的颜色从合成图像中去掉。

正片叠底模式(Multiply模式)——正片叠底模式。考察每个通道里的颜色信息,并对底层颜色进行正片叠加处理。其原理和色彩模式中的“减色原理”是一样的。这样混合产生的颜色总是比原来的要暗。如果和黑色发生正片叠底的话,产生的就只有黑色。而与白色混合就不会对原来的颜色产生任何影响。将上下两层图层像素颜色的灰度级进行乘法计算,获得灰度级更低的颜色而成为合成后的颜色,图层合成后的效果简单地说是低灰阶的像素显现而高灰阶不显现(即深色出现,浅色不出现),产生类似正片叠加的效果。(说明:黑色灰度级为0,白色灰度级为255)
这种模式可用来着色并作为一个图像层的模式。MuItiply模式从背景图像中减去源材 料(不论是在层上着色还是放在层上)的亮度值,得到最终的合成像素颜色。在MuItiply模式中应用较淡的颜色对图像的最终像素颜色没有影响。 MuItiply模式模拟阴影是很捧的。现实中的阴影从来也不会描绘出比源材料(阴影)或背景(获得阴影的区域)更淡的颜色或色调的特征。用户将在本章中使用MuItiply模式在恢复的图像中对Lee加入一个下拉阴影。

颜色加深(Color Burn模式)——使用这种模式时,会加暗图层的颜色值,加上的颜色越亮,效果越细腻。让底层的颜色变暗,有点类似于正片叠底,但不同的是,它会根据叠加的像素颜色相应增加底层的对比度。和白色混合没有效果。
除了背景上的较淡区域消失,且图像区域呈现尖锐的边缘特性之外,这种colo,Burn模式创建的效果类似于由MuItiply模式创建的效果。

线性颜色加深模式(Linear Burn模式)——同样类似于正片叠底,通过降低亮度,让底色变暗以反映混合色彩。和白色混合没有效果。

变亮混合模式变亮模式(Lighten模式)——与变暗模式相反,变亮混合模式是将两像素的RGB值进行比较后,取高值成为混合后的颜色,因而总的颜色灰度级升高,造成变亮的效果。用黑色合成图像时无作用,用白色时则仍为白色。变亮模式。和变暗模式相反,比较相互混合的像素亮度,选择混合颜色中较亮的像素保留起来,而其他较暗的像素则被替代。
在这种与Darken模式相反的模式下,较淡的颜色区域在合成图像中占主要地位。在层上的较暗区域,或在Lighten模式中采用的着色,并不出现在合成图像中。

屏幕模式(也叫滤色,Screen模式)——它与正片叠底模式相反,合成图层的效果是显现两图层中较高的灰阶,而较低的灰阶则不显现(即浅色出现,深色不出现),产生出一种漂白的效果。产生一幅更加明亮的图像。按照色彩混合原理中的“增色模式”混合。也就是说,对于屏幕模式,颜色具有相加效应。比如,当红色、绿色与蓝色都是最大值255的时候,以Screen模式混合就会得到RGB值为(255,255,255)的白色。而相反的,黑色意味着为0。所以,与黑色以该种模式混合没有任何效果,而与白色混合则得到RGB颜色最大值白色(RGB值为255,255,255)。
Screen模式是Muliiply的反模式。无论在Screen模式下用着色工具采用一种颜色,还是对Screen模式指定一个层,源图像同背景合并的结果始终是相同的合成颜色或一种更淡的颜色。此屏幕模式对于在图像中创建霓虹辉光效果是有用的。如果在层上围绕背景对象的边缘涂了白色(或任何淡颜色),然后指定层Screen模式,通过调节层的opacity设置就能 获得饱满或稀薄的辉光效果。

颜色减淡(Color Dodge模式)——使用这种模式时,会加亮图层的颜色值,加上的颜色越暗,效果越细腻。与Color Burn刚好相反,通过降低对比度,加亮底层颜色来反映混合色彩。与黑色混合没有任何效果。
除了指定在这个模式的层上边缘区域更尖锐,以及在这个模式下着色的笔划之外, Color Dodge模式类似于Screen模式创建的效果。另外,不管何时定义color Dodge模式混合前景与背景像素,背景图像上的暗区域都将会消失。

线性减淡(Linear Dodge模式)——线性颜色减淡模式。类似于颜色减淡模式。但是通过增加亮度来使得底层颜色变亮,以此获得混合色彩。与黑色混合没有任何效果。

对比度混合模式叠加模式(Overlay模式)——采用此模式合并图像时,综合了相乘和屏幕模式两种模式的方法。即根据底层的色彩决定将目标层的哪些像素以相乘模式合成,哪些像素以屏幕模式合成。合成后有些区域图变暗有些区域变亮。一般来说,发生变化的都是中间色调,高色和暗色区域基本保持不变。像素是进行Multiply(正片叠底)混合还是Screen(屏幕)混合,取决于底层颜色。颜色会被混合,但底层颜色的高光与阴影部分的亮度细节就会被保留。
这种模式以一种非艺术逻辑的方式把放置或应用到一个层上的颜色同背景色进行混合,然而,却能得到有趣的效果。背景图像中的纯黑色或纯白色区域无法在Overlay模式下显示层上的Overlay着色或图像区域。背景区域上落在黑色和白色之间的亮度值同0ver1ay 材料的颜色混合在一起,产生最终的合成颜色。为了使背景图像看上去好像是同设计或文本一起拍摄的,Overlay可用来在背景图像上画上一个设计或文本。

柔光模式(Soft Light模式)--作用效果如同是打上一层色调柔和的光,因而被我们称之为柔光。作用时将上层图像以柔光的方式施加到下层。当底层图层的灰阶趋于高或低,则会调整图层合成结果的阶调趋于中间的灰阶调,而获得色彩较为柔和的合成效果。形成的结果是:图像的中亮色调区域变得更亮,暗色区域变得更暗,图像反差增大类似于柔光灯的照射图像的效果。变暗还是提亮画面颜色,取决于上层颜色信息。产生的效果类似于为图像打上一盏散射的聚光灯。如果上层颜色(光源)亮度高于50%灰,底层会被照亮(变淡)。如果上层颜色(光源)亮度低于50%灰,底层会变暗,就好像被烧焦了似的。如果直接使用黑色或白色去进行混合的话,能产生明显的变暗或者提亮效应,但是不会让覆盖区域产生纯黑或者纯白。
Soft Light模式根据背景中的颜色色调,把颜色用于变暗或加亮背景图像。例如,如果在背景图像上涂了50%黑色,这是一个从黑色到白色的梯度,那着色时梯度的较暗区域变得更暗,而较亮区域呈现出更亮的色调。

强光模式(Hard Light模式)——作用效果如同是打上一层色调强烈的光所以称之为强光,所以如果两层中颜色的灰阶是偏向低灰阶,作用与正片叠底模式类似,而当偏向高灰阶时,则与屏幕模式类似。中间阶调作用不明显。正片叠底或者是屏幕混合底层颜色,取决于上层颜色。产生的效果就好像为图像应用强烈的聚光灯一样。如果上层颜色(光源)亮度高于50%灰,图像就会被照亮,这时混合方式类似于Screen(屏幕模式)。反之,如果亮度低于50%灰,图像就会变暗,这时混合方式就类似于Multiply(正片叠底模式)。该模式能为图像添加阴影。如果用纯黑或者纯白来进行混合,得到的也将是纯黑或者纯白。
除了根据背景中的颜色而使背景色是多重的或屏蔽的之外,这种模式实质上同Soft Lishi模式是一样的。它的效果要比Soft Light模式更强烈一些,同Overlay一样,这种模式也可以在背景对象的表面模拟图案或文本。

亮光模式(艳光模式,Vivid Light模式)——调整对比度以加深或减淡颜色,取决于上层图像的颜色分布。如果上层颜色(光源)亮度高于50%灰,图像将被降低对比度并且变亮;如果上层颜色(光源)亮度低于50%灰,图像会被提高对比度并且变暗。

线性光模式(Linear Light模式)——如果上层颜色(光源)亮度高于中性灰(50%灰),则用增加亮度的方法来使得画面变亮,反之用降低亮度的方法来使画面变暗。

固定光模式(点光,Pin Light模式)——按照上层颜色分布信息来替换颜色。如果上层颜色(光源)亮度高于50%灰,比上层颜色暗的像素将会被取代,而较之亮的像素则不发生变化。如果上层颜色(光源)亮度低于50%灰,比上层颜色亮的像素会被取代,而较之暗的像素则不发生变化。

实色混合(强混合模式,Hard Mix模式)——PhotoShop CS 新增了一个称为“实色”的新混合模式,选择此模式后,该图层图像的颜色会和下一层图层图像中的颜色进行混合,通常情况下,当混合两个图层以后结果是:亮色更加亮了,暗色更加暗了,降低填充不透明度建立多色调分色或者阈值,降低填充不透明度能使混合结果变得柔和。实色混合模式对于一个图像本身是具有不确定性的,例如它锐化图像时填充不透明度将控制锐化强度的大小。
新的“实色”混合模式产生招贴画式的混合效果,制作了一个多色调分色的图片,混合结果由红、绿、蓝、青、品红(洋红)、黄、黑和白八种颜色组成。混合的颜色由底层颜色与混合图层亮度决定(混合色是基色和混合色亮度的乘积)。

1.通过调整图层来决定具体色调
2.通过对灰度的调整或编辑来决定大致的阙值轮廓
3.通过对原图的色彩调整来决定不同色调的分布(推荐用曲线调整不同的通道)

比较混合模式差值(差异模式,Difference模式)——作用时,将要混合图层双方的RGB值中每个值分别进行比较,用高值减去低值作为合成后的颜色。所以这种模式也常使用,例如通常用白色图层合成一图像时,可以得到负片效果的反相图像。根据上下两边颜色的亮度分布,对上下像素的颜色值进行相减处理。比如,用最大值白色来进行Difference运算,会得到反相效果(下层颜色被减去,得到补值),而用黑色的话不发生任何变化(黑色亮度最低,下层颜色减去最小颜色值0,结果和原来一样)。
Difference模式使用层上的中间色调或中间色调的着色是最好不过的。这种模式创建背景颜色的相反色彩。例如,在Difference模式下,当把蓝色应用到绿色背景中时将产生一种 青绿组合色。此模式适用于模拟原始设计的底片,而且尤其可用来在其背景颜色从一个区域到另一区域发生变化的图像中生成突出效果。

排除模式(Exclusion模式)——Exclusion:与Difference作用类似,用较高阶或较低阶颜色去合成图像时与Difference毫无分别,使用趋近中间阶调颜色则效果有区别,总的来说效果比Difference要柔和。排除模式。和Difference类似,但是产生的对比度会较低。同样的,与纯白混合得到反相效果,而与纯黑混合没有任何变化。
这种模式产生一种比D1fference模式更柔和、更明亮的效果。无论是Difference还是 Exclusion模式都能使人物或自然景色图像产生更真实或更吸引人的图像合成。

成分混合模式色相(色调模式,Hue模式)——合成时,用当前图层的色相值去替换下层图像的色相值,而饱和度与亮度不变。决定生成颜色的参数包括:底层颜色的明度与饱和度,上层颜色的色调。
在这种模式下,层的色值或着色的颜色将代替底层背景图像的色彩。在使用此模式时想到Hue,Saturation,Brightness(HSB)颜色模式是有帮助的。Hue模式代替了基本的颜色成分迫不影响背景图像的饱和度或亮度。饱和度模式(Saturation模式)——合成时,用当前图层的饱和度去替换下层图像的饱和度,而色相值与亮度不变。饱和度模式。决定生成颜色的参数包括:底层颜色的明度与色调,上层颜色的饱和度。按这种模式与饱和度为0的颜色混合(灰色)不产生任何变化。
此模式使用层上颜色(或用着色工具使用的颜色)的强度(颜色纯度),且根据颜色强度强调背景图像上的颜色。例如,在把纯蓝色应用到一个灰暗的背景图像中时,显出了背景中的原始纯色,但蓝色并未加入到合成图像中。如果选择一种中性颜色(一种并不显示主流色度的颜色),对背景图像不发生任何变化。Saturation模式可用来显出图像中颜色强度已经由于岁月变得灰暗的底层颜色。颜色模式(着色模式,Color模式)——兼有以上两种模式,用当前图层的色相值与饱和度替换下层图像的色相值和饱和度,而亮度保持不变。决定生成颜色的参数包括:底层颜色的明度,上层颜色的色调与饱和度。这种模式能保留原有图像的灰度细节。这种模式能用来对黑白或者是不饱和的图像上色。亮度模式(明度模式,Luminosity模式)——合成两图层时,用当前图层的亮度值去替换下层图像的亮度值,而色相值与饱和度不变。决定生成颜色的参数包括:底层颜色的色调与饱和度,上层颜色的明度。 附加混合模式相加模式——可以在“应用图像”和“计算”对话框中访问该模式,相加模式通过增加像素值使图像变亮。将原图像中每个像素的亮度值与目标图像相对应的像素的亮度值相加,然后再除以范围值,最后加上偏移值。计算公式是:[(目标+源)/范围]+偏移=亮度。减去模式——可以在“应用图像”和“计算”对话框中访问该模式。从目标图像相对应的像素的亮度值中减去源图像中每个像素的亮度值,然后除以范围值,最后加上偏移值。减去模式使图像变暗。计算公式是:[(目标-源)/范围]+偏移=亮度。背后模式——同绘制工具一起使用。该模式限制当前绘制工具只能在图层的透明部分产生效果,而且同时必须保证没有选中“锁定透明像素”单选图标。清除模式——同绘制工具一起使用。该模式使用透明像素填充区域。阈值模式——该模式是不支持图层的位图图像或索引颜色图像的默认模式,它的效果和正常模式相似。
参考技术A 1. RGB色彩模式
自然界中绝大部分的可见光谱可以用红、绿和蓝三色光按不同比例和强度的混合来表示。RGB分别代表着3种颜色:R代表红色,G代表绿色、B代表蓝色。RGB模型也称为加色模型,如图5所示。RGB模型通常用于光照、视频和屏幕图像编辑。

RGB色彩模式使用RGB模型为图像中每一个像素的RGB分量分配一个0~255范围内

的强度值。例如:纯红色R值为255,G值为0,B值为0;灰色的R、G、B三个值相等(除了0和255);白色的R、G、B都为255;黑色的R、G、B都为0。RGB图像只使用三种颜色,就可以使它们按照不同的比例混合,在屏幕上重现16581375种颜色。

2. CMYK色彩模式

CMYK色彩模式以打印油墨在纸张上的光线吸收特性为基础,图像中每个像素都是由靛青(C)、品红(M)、黄(Y)和黑(K)色按照不同的比例合成。每个像素的每种印刷油墨会被分配一个百分比值,最亮(高光)的颜色分配较低的印刷油墨颜色百分比值,较暗(暗调)的颜色分配较高的百分比值。例如,明亮的红色可能会包含2%青色、93%洋红、90%黄色和0%黑色。在 CMYK 图像中,当所有4种分量的值都是0%时,就会产生纯白色。CMYK色彩模式的图像中包含四个通道,如图6所示。我们所看见的图形是由这4个通道合成的效果。

在制作用于印刷色打印的图像时,要使用CMYK色彩模式。RGB色彩模式的图像转换成CMYK色彩模式的图像会产生分色。如果您使用的图像素材为RGB色彩模式,最好在编辑完成后再转换为CMYK色彩模式。

3. HSB色彩模式
HSB色彩模式是根据日常生活中人眼的视觉特征而制定的一套色彩模式,最接近于人类对色彩辨认的思考方式。HSB色彩模式以色相(H)、饱和度(S)和亮度(B)描述颜色的基本特征。

色相指从物体反射或透过物体传播的颜色。在0到360度的标准色轮上,色相是按位置计量的。在通常的使用中,色相由颜色名称标识,比如红、橙或绿色。

饱和度是指颜色的强度或纯度,用色相中灰色成分所占的比例来表示,0%为纯灰色,100%为完全饱和。在标准色轮上,从中心位置到边缘位置的饱和度是递增的。

亮度是指颜色的相对明暗程度,通常将0%定义为黑色,100%定义为白色。

HSB色彩模式比前面介绍的两种色彩模式更容易理解。但由于设备的限制,在计算机屏幕上显示时,要转换为RGB模式,作为打印输出时,要转换为CMYK模式。这在一定程度上限制了HSB模式的使用。

4. Lab色彩模式
Lab色彩模式由光度分量(L)和两个色度分量组成,这两个分量即a分量(从绿到红)和b分量(从蓝到黄),如图8所示。Lab色彩模式与设备无关,不管使用什么设备(如显示器、打印机或扫描仪)创建或输出图像,这种色彩模式产生的颜色都保持一致。

Lab色彩模式通常用于处理Photo CD(照片光盘)图像、单独编辑图像中的亮度和颜色值、在不同系统间转移图像以及打印到PostScript(R)Level 2和Level 3打印机。

5. Indexed Color(索引)色彩模式

索引色彩模式最多使用256种颜色,当您将图像转换为索引色彩模式时,通常会构建一个调色板存放并索引图像中的颜色。如果原图像中的一种颜色没有出现在调色板中,程序会选取已有颜色中最相近的颜色或使用已有颜色模拟该种颜色。

在索引色彩模式下,通过限制调色板中颜色的数目可以减小文件大小,同时保持视觉上的品质不变。在网页中常常需要使用索引模式的图像。

6. Bitmap(位图)色彩模式

位图模式的图像只有黑色与白色两种像素组成,每一个像素用“位”来表示。“位”只有两种状态:0表示有点,1表示无点。位图模式主要用于早期不能识别颜色和灰度的设备。如果需要表示灰度,则需要通过点的抖动来模拟。

位图模式通常用于文字识别,如果扫描需要使用OCR(光学文字识别)技术识别的图像文件,须将图像转化为位图模式。

7. Grayscale(灰度)色彩模式

灰度模式最多使用256级灰度来表现图像,图像中的每个像素有一个0(黑色)到255(白色)之间的亮度值。灰度值也可以用黑色油墨覆盖的百分比来表示(0%表示白色,100%表示黑色)。

在将彩色图像转换灰度模式的图像时,会扔掉原图像中所有的色彩信息。与位图模式相比,灰度模式能够更好地表现高品质的图像效果。

需要注意的是,尽管一些图像处理软件允许您将一个灰度模式的图像重新转换为彩色模式的图像,但转换后不可能将原先丢失的颜色恢复,您只能为图像重新上色。所以,在将彩色模式的图像转换为灰度模式的图像时,应尽量保留备份文件。

16位通道在印刷出来时颜色要比8位通道的颜色丰富点
参考技术B 1、灰度的比索引的图文件还要小
2、灰度的显示只是黑白两色,而索引的是256色的,差别很大3.Lab色彩模型是由照度(L)和有关色彩的a, b三个要素组成。L表示照度(
Luminosity),相当于亮度,a表示从红色至绿色的范围,b表示从黄色至蓝色的
范围。L的值域由0到100,L=50时,就相当于50%的黑;a和b的值域都是由+120至
-120,其中+120 a就是红色,渐渐过渡到-120 a的时候就变成绿色;同样原理,
+120 b是黄色,-120 b是蓝色。所有的颜色就以这三个值交互变化所组成。例如
,一块色彩的Lab值是L = 100,a = 30, b = 0, 这块色彩就是粉红色。
C. 青色(Cyan) M. 洋红色(Magenta) Y. 黄色(Yellow) K. 黑色(blacK) 4.在灰度RGB或CMYK模式下,可以使用16位通道来代替默认的8位通道。

根据默认情况,8位通道中包含256个色阶,如果增到16位,每个通道的色阶数量为65536个,这样能得到更多的色彩细节。

Photoshop可以识别和输入16位通道的图像,但对于这种图像限制很多,所有的滤镜都不能使用,另外16位通道模式的图像不能被印刷 在灰度RGB或CMYK模式下,可以使用16位通道来代替默认的8位通道。

根据默认情况,8位通道中包含256个色阶,如果增到16位,每个通道的色阶数量为65536个,这样能得到更多的色彩细节。

Photoshop可以识别和输入16位通道的图像,但对于这种图像限制很多,所有的滤镜都不能使用,另外16位通道模式的图像不能被印刷
参考技术C 灰度就是黑白图片,改了这个模式就不能上色了。颜色索引可以动画,还可以用来做火焰字等等。LAB .这个其实不太常用的多通道是专色用这个其实也没什么大作用16位/通道只要记住不能印刷就好了RGB模式就是一般可以打印的模式还有其它的模式你也可以自己试试,都有不同的用途,但是作用不多也很杂,自己试试就知道了。

基于OpenCV实现Photoshop的17种图层混合

一、图层混合模式是什么?

    所谓图层混合模式就是指一个层与其下图层的色彩叠加方式,在这之前我们所使用的是正常模式,除了正常以外,还有很多种混合模式,它们都可以产生迥异的合成效果。

技术图片

二、PhotoShop的27种混合模式

从很久之前的版本开始,PhotoShop就保持了27种图层混合模式。

技术图片技术图片

并且可以进一步分为:普通模式、变暗模式、变亮模式、饱和度模式、差集模式和颜色模式。

 

技术图片

 

      1. 正常(Normal)模式
    在“正常”模式下,“混合色”的显示与不透明度的设置有关。当“不透明度”为100%,也就是说完全不透明时,“结果色”的像素将完全由所用的“混合色”代替;当“不透明度”小于100%时,混合色的像素会透过所用的颜色显示出来,显示的程度取决于不透明度的设置与“基色”的颜色
  2. 溶解(Dissolve)模式
  在“溶解”模式中,根据任何像素位置的不透明度,“结果色”由“基色”或“混合色”的像素随机替换。

  3. 变暗(Darken)模式
  在“变暗”模式中,查看每个通道中的颜色信息,并选择“基色”或“混合色”中较暗的颜色作为“结果色”。比“混合色”亮的像素被替换,比“混合色”暗的像素保持不变。“变暗”模式将导致比背景颜色更淡的颜色从“结果色”中被去掉了。

  4. 正片叠底(Multiply)模式
  在“正片叠底”模式中,查看每个通道中的颜色信息,并将“基色”与“混合色”复合。“结果色”总是较暗的颜色。任何颜色与黑色复合产生黑色。任何颜色与白色复合保持不变。

  5. 颜色加深(Clolor Burn)模式
  在“颜色加深”模式中,查看每个通道中的颜色信息,并通过增加对比度使基色变暗以反映混合色,如果与白色混合的话将不会产生变化。

  6. 线性加深(Linear Burn)模式
  在“线性加深”模式中,查看每个通道中的颜色信息,并通过减小亮度使“基色”变暗以反映混合色。如果“混合色”与“基色”上的白色混合后将不会产生变化,

  7. 变亮(Lighten)模式
  在“变亮”模式中,查看每个通道中的颜色信息,并选择“基色”或“混合色”中较亮的颜色作为“结果色”。比“混合色”暗的像素被替换,比“混合色”亮的像素保持不变。 在这种与“变暗”模式相反的模式下,较淡的颜色区域在最终的“合成色”中占主要地位。

  8. 滤色(Screen)模式
  “滤色”模式与“正片叠底”模式正好相反,它将图像的“基色”颜色与“混合色”颜色结合起来产生比两种颜色都浅的第三种颜色。
  9. 颜色减淡(Clolor Dodge)模式
  在“颜色减淡”模式中,查看每个通道中的颜色信息,并通过减小对比度使基色变亮以反映混合色。与黑色混合则不发生变化。

  10. 线性减淡(Linear Dodge)模式
  在“线性减淡”模式中,查看每个通道中的颜色信息,并通过增加亮度使基色变亮以反映混合色。

  11. 叠加(Overlay)模式
  “叠加”模式把图像的“基色”颜色与“混合色”颜色相混合产生一种中间色。“基色”内颜色比“混合色”颜色暗的颜色使“混合色”颜色倍增,比“混合色”颜色亮的颜色将使“混合色”颜色被遮盖,而图像内的高亮部分和阴影部分保持不变,因此对黑色或白色像素着色时“叠加”模式不起作用。“叠加”模式以一种非艺术逻辑的方式把放置或应用到一个层上的颜色同背景色进行混合,然而,却能得到有趣的效果。背景图像中的纯黑色或纯白色区域无法在“叠加”模式下显示层上的“叠加”着色或图像区域。背景区域上落在黑色和白色之间的亮度值同“叠加”材料的颜色混合在一起,产生最终的合成颜色。为了使背景图像看上去好像是同设计或文本一起拍摄的。

  12. 柔光(Soft Light)模式
  “柔光”模式会产生一种柔光照射的效果。如果“混合色”颜色比“基色颜色的像素更亮一些,那么“结果色”将更亮;如果“混合色”颜色比“基色”颜色的像素更暗一些,那么“结果色”颜色将更暗,使图像的亮度反差增大。例如,如果在背景图像上涂了50%黑色,这是一个从黑色到白色的梯度,那着色时梯度的较暗区域变得更暗,而较亮区域呈现出更亮的色调。 其实使颜色变亮或变暗,具体取决于“混合色”。此效果与发散的聚光灯照在图像上相似。 如果“混合色”比 50% 灰色亮,则图像变亮,就像被减淡了一样。如果“混合色”比 50% 灰色暗,则图像变暗,就象被加深了一样。用纯黑色或纯白色绘画会产生明显较暗或较亮的区域,但不会产生纯黑色或纯白色。
  13. 强光(Hard Light)模式
  “强光”模式将产生一种强光照射的效果。如果“混合色”颜色“基色”颜色的像素更亮一些,那么“结果色”颜色将更亮;如果“混合色”颜色比“基色”颜色的像素更暗一些,那么“结果色”将更暗。除了根据背景中的颜色而使背景色是多重的或屏蔽的之外,这种模式实质上同“柔光”模式是一样的。它的效果要比“柔光”模式更强烈一些,同“叠加”一样,这种模式也可以在背景对象的表面模拟图案或文本,例如,如果混合色比 50% 灰色亮,则图像变亮,就像过滤后的效果。这对于向图像中添加高光非常有用。如果混合色比 50%灰色暗,则图像变暗,就像复合后的效果。这对于向图像添加暗调非常有用。用纯黑色或纯白色绘画会产生纯黑色或纯白色。
  14. 亮光(Vivid Light)模式
  通过增加或减小对比度来加深或减淡颜色,具体取决于混合色。如果混合色(光源)比 50% 灰色亮,则通过减小对比度使图像变亮。如果混合色比 50% 灰色暗,则通过增加对比度使图像变暗,

  15. 线性光(Linear Light)模式
  通过减小或增加亮度来加深或减淡颜色,具体取决于混合色。如果混合色(光源)比 50% 灰色亮,则通过增加亮度使图像变亮。如果混合色比 50% 灰色暗,则通过减小亮度使图像变暗。

  16. 点光(Pin Light)模式
  “点光”模式其实就是替换颜色,其具体取决于“混合色”。如果“混合色”比 50% 灰色亮,则替换比“混合色”暗的像素,而不改变比“混合色”亮的像素。如果“混合色”比 50% 灰色暗,则替换比“混合色”亮的像素,而不改变比“混合色”暗的像素。这对于向图像添加特殊效果非常有用。

  17. 差值(Diference)模式
  在“差值”模式中,查看每个通道中的颜色信息,“差值”模式是将从图像中“基色”颜色的亮度值减去“混合色”颜色的亮度值,如果结果为负,则取正值,产生反相效果。由于黑色的亮度值为0,白色的亮度值为255,因此用黑色着色不会产生任何影响,用白色着色则产生被着色的原始像素颜色的反相。“差值”模式创建背景颜色的相反色彩,例如,在“差值”模式下,当把蓝色应用到绿色背景中时将产生一种青绿组合色。“差值”模式适用于模拟原始设计的底片,而且尤其可用来在其背景颜色从一个区域到另一区域发生变化的图像中生成突出效果。

  18. 排除(Exclusion)模式
  “排除”模式与“差值”模式相似,但是具有高对比度和低饱和度的特点。比用“差值”模式获得的颜色要柔和、更明亮一些。建议你在处理图像时,首先选择“差值”模式,若效果不够理想,可以选择“排除”模式来试试。其中与白色混合将反转“基色”值,而与黑色混合则不发生变化。其实无论是“差值”模式还是“排除”模式都能使人物或自然景色图像产生更真实或更吸引人的图像合成。

  19. 色相(Hue)模式
  “色相”模式只用“混合色”颜色的色相值进行着色,而使饱和度和亮度值保持不变。当“基色”颜色与“混合色”颜色的色相值不同时,才能使用描绘颜色进行着色,如图30所示。但是要注意的是“色相”模式不能用于灰度模式的图像。

  20. 饱和度(Saturation)模式
  “饱和度”模式的作用方式与“色相”模式相似,它只用“混合色”颜色的饱和度值进行着色,而使色相值和亮度值保持不变。当“基色”颜色与“混合色”颜色的饱和度值不同时,才能使用描绘颜色进行着色处理,如图31所示。在无饱和度的区域上(也就是灰色区域中)用“饱和度”模式是不会产生任何效果的。

  21. 颜色(Color)模式
  “颜色”模式能够使用“混合色”颜色的饱和度值和色相值同时进行着色,而使“基色”颜色的亮度值保持不变。“颜色”模式模式可以看成是“饱合度”模式和“色相”模式的综合效果。该模式能够使灰色图像的阴影或轮廓透过着色的颜色显示出来,产生某种色彩化的效果。这样可以保留图像中的灰阶,并且对于给单色图像上色和给彩色图像着色都会非常有用。

  22. 亮度(Luminosity)模式
  “亮度”模式能够使用“混合色”颜色的亮度值进行着色,而保持“基色”颜色的饱和度和色相数值不变。其实就是用“基色”中的“色相”和“饱和度”以及“混合色”的亮度创建“结果色”。

 

三、代码实现:

其实这里的混合算法大多不复杂,特别是在有算法文档 http://www.deepskycolors.com/archivo/2010/04/21/formulas-for-Photoshop-blending-modes.html。支持的前提下,这里我们就文档中提到的16种再加上我之前有研究过的划分算法,整理出表格。

 

Blend mode Formula
Darken min(Target,Blend)         
Multiply Target * Blend         
Color Burn 1 - (1-Target) / Blend         
Linear Burn Target + Blend - 1         
Lighten max(Target,Blend)         
Screen 1 - (1-Target) * (1-Blend)         
Color Dodge Target / (1-Blend)         
Linear Dodge Target + Blend         
Overlay (Target > 0.5) * (1 - (1-2*(Target-0.5)) * (1-Blend)) +
(Target <= 0.5) * ((2*Target) * Blend)
Soft Light (Blend > 0.5) * (1 - (1-Target) * (1-(Blend-0.5))) +
(Blend <= 0.5) * (Target * (Blend+0.5))
Hard Light (Blend > 0.5) * (1 - (1-Target) * (1-2*(Blend-0.5))) +
(Blend <= 0.5) * (Target * (2*Blend))
Vivid Light (Blend > 0.5) * (1 - (1-Target) / (2*(Blend-0.5))) +
(Blend <= 0.5) * (Target / (1-2*Blend))
Linear Light (Blend > 0.5) * (Target + 2*(Blend-0.5)) +
(Blend <= 0.5) * (Target + 2*Blend - 1)
Pin Light (Blend > 0.5) * (max(Target,2*(Blend-0.5))) +
(Blend <= 0.5) * (min(Target,2*Blend)))
Difference | Target - Blend |         
Exclusion 0.5 - 2*(Target-0.5)*(Blend-0.5)

 

编写具有OpenCV风格的代码:

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
 
using namespace std;
using namespace cv;
 
#define EPSILON      1e-6f
 
#define SAFE_DIV_MIN EPSILON
#define SAFE_DIV_MAX (1.0f / SAFE_DIV_MIN)
 
#define    CLAMP(f,min,max)    ((f)<(min)?(min):(f)>(max)?(max):(f))
//! layerModelBlending algorithm flags
enum
{
    DARKEN = 1,                //min(Target,Blend)
    MULTIPY = 2,               //Target * Blend      
    COLOR_BURN = 3,            //1 - (1-Target) / Blend         
    LINEAR_BRUN = 4,            //Target + Blend - 1         
    LIGHTEN = 5,               //max(Target,Blend)       
    SCREEN = 6,                //1 - (1-Target) * (1-Blend)         
    COLOR_DODGE = 7,           //Target / (1-Blend)         
    LINEAR_DODGE = 8,          //Target + Blend         
    OVERLAY = 9,               //(Target > 0.5) * (1 - (1-2*(Target-0.5)) * (1-Blend)) +(Target <= 0.5) * ((2*Target) * Blend)
    SOFT_LIGHT = 10,           //(Blend > 0.5) * (1 - (1-Target) * (1-(Blend-0.5))) +(Blend <= 0.5) * (Target * (Blend+0.5))
    HARD_LIGHT = 11,           //(Blend > 0.5) * (1 - (1-Target) * (1-2*(Blend-0.5))) +(Blend <= 0.5) * (Target * (2*Blend))
    VIVID_LIGHT = 12,          //(Blend > 0.5) * (1 - (1-Target) / (2*(Blend-0.5))) +(Blend <= 0.5) * (Target / (1-2*Blend))
    LINEAR_LIGHT = 13,         //(Blend > 0.5) * (Target + 2*(Blend-0.5)) +(Blend <= 0.5) * (Target + 2*Blend - 1)
    PIN_LIGHT = 14,            //(Blend > 0.5) * (max(Target,2*(Blend-0.5))) +(Blend <= 0.5) * (min(Target,2*Blend)))
    DIFFERENCE = 15,           //| Target - Blend |         
    EXCLUSION = 16,            //0.5 - 2*(Target-0.5)*(Blend-0.5)
    DIVIDE = 17                //Target/Blend
 

};

/*  local function prototypes  */
static inline float    safe_div(float afloat b);
/* returns a / b, clamped to [-SAFE_DIV_MAX, SAFE_DIV_MAX].
 * if -SAFE_DIV_MIN <= a <= SAFE_DIV_MIN, returns 0.
 */
static inline float safe_div(float afloat b)
{
    float result = 0.0f;
 
    if (fabsf(a) > SAFE_DIV_MIN)
    {
        result = a / b;
        result = CLAMP(result, -SAFE_DIV_MAXSAFE_DIV_MAX);
    }
 
    return result;
}
//TODO target和blend应该是同样大小

CV_EXPORTS_W void layerModelBlending(Mat targetMat blendMat dstint flag);

CV_EXPORTS_W void layerModelBlending(Mat targetMat blendMat dstint flag)
{
    for (int index_row = 0; index_row < target.rowsindex_row++)
        for (int index_col = 0; index_col < target.colsindex_col++)
            for (int index_c = 0; index_c < 3; index_c++)
                switch (flag)
                {
                case DARKEN:
                    dst.at<Vec3f>(index_rowindex_col)[index_c] = min(
                        target.at<Vec3f>(index_rowindex_col)[index_c],
                        blend.at<Vec3f>(index_rowindex_col)[index_c]);
                    break;
                case MULTIPY:
                    dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        target.at<Vec3f>(index_rowindex_col)[index_c] *
                        blend.at<Vec3f>(index_rowindex_col)[index_c];
                    break;
                case COLOR_BURN:
                    dst.at<Vec3f>(index_rowindex_col)[index_c] = 1 -
                        safe_div((1 - target.at<Vec3f>(index_rowindex_col)[index_c]),
                            blend.at<Vec3f>(index_rowindex_col)[index_c]);
                    break;
                case LINEAR_BRUN:
                    dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        target.at<Vec3f>(index_rowindex_col)[index_c] +
                        blend.at<Vec3f>(index_rowindex_col)[index_c] - 1;
                    break;
                case LIGHTEN:
                    dst.at<Vec3f>(index_rowindex_col)[index_c] = max(
                        target.at<Vec3f>(index_rowindex_col)[index_c],
                        blend.at<Vec3f>(index_rowindex_col)[index_c]);
                    break;
                case SCREEN:
                    dst.at<Vec3f>(index_rowindex_col)[index_c] = 1 -
                        (1 - target.at<Vec3f>(index_rowindex_col)[index_c]) *
                        (1 - blend.at<Vec3f>(index_rowindex_col)[index_c]);
                    break;
                case COLOR_DODGE:
                    dst.at<Vec3f>(index_rowindex_col)[index_c] = safe_div
                    (target.at<Vec3f>(index_rowindex_col)[index_c],
                        1 - blend.at<Vec3f>(index_rowindex_col)[index_c]);
                    break;
                case LINEAR_DODGE:
                    dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        target.at<Vec3f>(index_rowindex_col)[index_c] +
                        blend.at<Vec3f>(index_rowindex_col)[index_c];
                    break;
                case OVERLAY:
                    if (target.at<Vec3f>(index_rowindex_col)[index_c] > 0.5f)
                        dst.at<Vec3f>(index_rowindex_col)[index_c] = 1 -
                        (1 - 2 * (target.at<Vec3f>(index_rowindex_col)[index_c] - 0.5)) *
                        (1 - blend.at<Vec3f>(index_rowindex_col)[index_c]);
                    else
                        dst.at<Vec3f>(index_rowindex_col)[index_c] = 2 *
                        target.at<Vec3f>(index_rowindex_col)[index_c] *
                        blend.at<Vec3f>(index_rowindex_col)[index_c];
                    break;
                case SOFT_LIGHT:
                    if (target.at<Vec3f>(index_rowindex_col)[index_c] > 0.5f)
                        dst.at<Vec3f>(index_rowindex_col)[index_c] = 1 -
                        (1 - target.at<Vec3f>(index_rowindex_col)[index_c]) *
                        (1 - (blend.at<Vec3f>(index_rowindex_col)[index_c] - 0.5));
                    else
                        dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        target.at<Vec3f>(index_rowindex_col)[index_c] *
                        (blend.at<Vec3f>(index_rowindex_col)[index_c] + 0.5);
                    break;
                case HARD_LIGHT:
                    if (target.at<Vec3f>(index_rowindex_col)[index_c] > 0.5f)
                        dst.at<Vec3f>(index_rowindex_col)[index_c] = 1 -
                        (1 - target.at<Vec3f>(index_rowindex_col)[index_c]) *
                        (1 - 2 * blend.at<Vec3f>(index_rowindex_col)[index_c] - 0.5);
                    else
                        dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        target.at<Vec3f>(index_rowindex_col)[index_c] *
                        (2 * blend.at<Vec3f>(index_rowindex_col)[index_c]);
                    break;
                case VIVID_LIGHT:
                    if (target.at<Vec3f>(index_rowindex_col)[index_c] > 0.5f)
                        dst.at<Vec3f>(index_rowindex_col)[index_c] = 1 -
                        safe_div(1 - target.at<Vec3f>(index_rowindex_col)[index_c],
                        (2 * (blend.at<Vec3f>(index_rowindex_col)[index_c] - 0.5)));
                    else
                        dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        safe_div(target.at<Vec3f>(index_rowindex_col)[index_c],
                        (1 - 2 * blend.at<Vec3f>(index_rowindex_col)[index_c]));
                    break;
                case LINEAR_LIGHT:
                    if (target.at<Vec3f>(index_rowindex_col)[index_c] > 0.5f)
                        dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        target.at<Vec3f>(index_rowindex_col)[index_c] +
                        (2 * (blend.at<Vec3f>(index_rowindex_col)[index_c] - 0.5));
                    else
                        dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        target.at<Vec3f>(index_rowindex_col)[index_c] +
                        2 * blend.at<Vec3f>(index_rowindex_col)[index_c] - 1;
                    break;
                case PIN_LIGHT:
                    if (target.at<Vec3f>(index_rowindex_col)[index_c] > 0.5f)
                        dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        max(target.at<Vec3f>(index_rowindex_col)[index_c],
                        (float)(2 * (blend.at<Vec3f>(index_rowindex_col)[index_c] - 0.5)));
                    else
                        dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        min(target.at<Vec3f>(index_rowindex_col)[index_c],
                            2 * blend.at<Vec3f>(index_rowindex_col)[index_c]);
                    break;
                case DIFFERENCE:
                    dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        abs(target.at<Vec3f>(index_rowindex_col)[index_c] -
                            blend.at<Vec3f>(index_rowindex_col)[index_c]);
                    break;
                case EXCLUSION:
                    dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        target.at<Vec3f>(index_rowindex_col)[index_c] +
                        blend.at<Vec3f>(index_rowindex_col)[index_c] -
                        2 * target.at<Vec3f>(index_rowindex_col)[index_c] * blend.at<Vec3f>(index_rowindex_col)[index_c];
                    break;
                case DIVIDE:
                    dst.at<Vec3f>(index_rowindex_col)[index_c] =
                        safe_div(target.at<Vec3f>(index_rowindex_col)[index_c],
                            blend.at<Vec3f>(index_rowindex_col)[index_c]);
                    break;
                }

}

int main() {
    Mat target = cv::imread("e:/template/lena.jpg");
    Mat blend = cv::imread("e:/template/opencv-logo.png");
    Mat dst(target.size(), CV_32FC3Scalar::all(0));
    Mat dst2(target.size(), CV_8UC3Scalar::all(0));
    if (target.empty()) {
        std::cout << "Unable to load target! ";
    }
    if (blend.empty()) {
        std::cout << "Unable to load blend! ";
    }
    resize(blendblendtarget.size());
    target.convertTo(targetCV_32F, 1.0 / 255);
    blend.convertTo(blendCV_32F, 1.0 / 255);
 
    layerModelBlending(targetblenddstDARKEN);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/DARKEN_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstMULTIPY);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/MULTIPY_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstCOLOR_BURN);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/COLOR_BURN.jpg"dst2);
 
    layerModelBlending(targetblenddstLINEAR_BRUN);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/LINEAR_BRUN.jpg"dst2);
 
    layerModelBlending(targetblenddstLIGHTEN);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/LIGHTEN.jpg"dst2);
 
    layerModelBlending(targetblenddstSCREEN);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/SCREEN_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstCOLOR_DODGE);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/COLOR_DODGE_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstLINEAR_DODGE);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/LINEAR_DODGE_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstOVERLAY);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/OVERLAY_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstSOFT_LIGHT);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/SOFT_LIGHT_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstHARD_LIGHT);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/HARD_LIGHT_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstVIVID_LIGHT);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/VIVID_LIGHT_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstLINEAR_LIGHT);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/LINEAR_LIGHT_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstPIN_LIGHT);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/PIN_LIGHT_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstDIFFERENCE);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/DIFFERENCE_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstEXCLUSION);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/EXCLUSION_RESULT.jpg"dst2);
 
    layerModelBlending(targetblenddstDIVIDE);
    dst.convertTo(dst2CV_8UC3, 255);
    imwrite("E:/sandbox/layerBlendingModles/DIVIDE_RESULT.jpg"dst2);
}

17种结果展示如下。

技术图片

 

四、重要的参考:

在本例代码实现过程中,主要参考了两个方面的代码:

一个是GIMP的代码:来自gimpoperationlayermode-blend.h。

函数名称 核心代码
gimp_operation_layer_mode_blend_addition
for (c = 0; c < 3; c++)
            comp[c] = in[c] + layer[c];
gimp_operation_layer_mode_blend_burn
 for (c = 0; c < 3; c++)
            comp[c] = 1.0f - safe_div (1.0f - in[c], layer[c]);
gimp_operation_layer_mode_blend_darken_only
 for (c = 0; c < 3; c++)
            comp[c] = MIN (in[c], layer[c]);
gimp_operation_layer_mode_blend_difference
 for (c = 0; c < 3; c++)
            comp[c] = fabsf (in[c] - layer[c]);
gimp_operation_layer_mode_blend_divide (const gfloat *in,
for (c = 0; c < 3; c++)
            comp[c] = safe_div (in[c], layer[c]);
gimp_operation_layer_mode_blend_dodge
for (c = 0; c < 3; c++)
            comp[c] = safe_div (in[c], 1.0f - layer[c]);
gimp_operation_layer_mode_blend_exclusion
for (c = 0; c < 3; c++)
            comp[c] = 0.5f - 2.0f * (in[c] - 0.5f) * (layer[c] - 0.5f);
gimp_operation_layer_mode_blend_grain_extract
for (c = 0; c < 3; c++)
            comp[c] = in[c] - layer[c] + 0.5f;
gimp_operation_layer_mode_blend_grain_merge
for (c = 0; c < 3; c++)
            comp[c] = in[c] + layer[c] - 0.5f;
gimp_operation_layer_mode_blend_hard_mix
for (c = 0; c < 3; c++)
            comp[c] = in[c] + layer[c] < 1.0f ? 0.0f : 1.0f;
gimp_operation_layer_mode_blend_hardlight
for (c = 0; c < 3; c++)
            {
              gfloat val;

              if (layer[c] > 0.5f)
                {
                  val = (1.0f - in[c]) * (1.0f - (layer[c] - 0.5f) * 2.0f);
                  val = MIN (1.0f - val, 1.0f);
                }
              else
                {
                  val = in[c] * (layer[c] * 2.0f);
                  val = MIN (val, 1.0f);
                }

              comp[c] = val;
            }
gimp_operation_layer_mode_blend_hsl_color



未整理



gimp_operation_layer_mode_blend_hsv_hue
gimp_operation_layer_mode_blend_hsv_saturation
gimp_operation_layer_mode_blend_hsv_value
gimp_operation_layer_mode_blend_lch_chroma
gimp_operation_layer_mode_blend_lch_color
gimp_operation_layer_mode_blend_lch_hue
gimp_operation_layer_mode_blend_lch_lightness
if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
        {
          comp[0] = layer[0];
          comp[1] = in[1];
          comp[2] = in[2];
        }
gimp_operation_layer_mode_blend_lighten_only
 for (c = 0; c < 3; c++)
            comp[c] = MAX (in[c], layer[c]);
gimp_operation_layer_mode_blend_linear_burn
for (c = 0; c < 3; c++)
            comp[c] = in[c] + layer[c] - 1.0f;
gimp_operation_layer_mode_blend_linear_light
for (c = 0; c < 3; c++)
            {
              gfloat val;

              if (layer[c] <= 0.5f)
                val = in[c] + 2.0f * layer[c] - 1.0f;
              else
                val = in[c] + 2.0f * (layer[c] - 0.5f);

              comp[c] = val;
            }
gimp_operation_layer_mode_blend_luma_darken_only
 if (dest_luminance <= src_luminance)
            {
              for (c = 0; c < 3; c++)
                comp[c] = in[c];
            }
          else
            {
              for (c = 0; c < 3; c++)
                comp[c] = layer[c];
            }
gimp_operation_layer_mode_blend_luma_lighten_only
 if (dest_luminance >= src_luminance)
            {
              for (c = 0; c < 3; c++)
                comp[c] = in[c];
            }
          else
            {
              for (c = 0; c < 3; c++)
                comp[c] = layer[c];
            }
gimp_operation_layer_mode_blend_luminance
 if (layer[ALPHA] != 0.0f && in[ALPHA] != 0.0f)
        {
          gfloat ratio = safe_div (layer_Y_p[0], in_Y_p[0]);
          gint   c;

          for (c = 0; c < 3; c ++)
            comp[c] = in[c] * ratio;
        }
gimp_operation_layer_mode_blend_multiply
 for (c = 0; c < 3; c++)
            comp[c] = in[c] * layer[c];
gimp_operation_layer_mode_blend_overlay
for (c = 0; c < 3; c++)
            {
              gfloat val;

              if (in[c] < 0.5f)
                val = 2.0f * in[c] * layer[c];
              else
                val = 1.0f - 2.0f * (1.0f - layer[c]) * (1.0f - in[c]);

              comp[c] = val;
            }
gimp_operation_layer_mode_blend_pin_light
未整理

一个是网站的代码:来自https://blog.csdn.net/matrix_space

 

算法名 实现
溶解
Dissolve

// Dissolve
void Dissolve(Mat& src1, Mat& src2, Mat& dst, double alpha)
{
    dst=src1;
    Mat Rand_mat(src1.size(), CV_32FC1);
    cv::randu(Rand_mat, 0,1);
    float a=0;
    float b=0;
     for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            b=Rand_mat.at<float>(index_row, index_col);
            if(b<alpha)
            {
                for(int index_c=0; index_c<3; index_c++)
               {
                   a=src2.at<Vec3f>(index_row, index_col)[index_c];
                   dst.at<Vec3f>(index_row, index_col)[index_c]=a;
               }
            }
        }
    }
}
变暗
Darken
C = MIN(A,B)
// Darken
void Darken(Mat& src1, Mat& src2, Mat& dst)
{
     for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
                dst.at<Vec3f>(index_row, index_col)[index_c]=min(
                         src1.at<Vec3f>(index_row, index_col)[index_c],
                         src2.at<Vec3f>(index_row, index_col)[index_c]);
        }
    }
正片叠底
Multiply
C=A*B/255
// Multiply 正片叠底
void Multiply(Matsrc1Matsrc2Matdst)
{
    for(int index_row=0; index_row<src1.rowsindex_row++)
    {
        for(int index_col=0; index_col<src1.colsindex_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
                dst.at<Vec3f>(index_rowindex_col)[index_c]=
                src1.at<Vec3f>(index_rowindex_col)[index_c]*
                src2.at<Vec3f>(index_rowindex_col)[index_c];
        }
    }
}
颜色加深
Color_Burn
C = A-((255-A)×(255-B))/ B

// Color_Burn 颜色加深
void Color_Burn(Matsrc1Matsrc2Matdst)
{
    for(int index_row=0; index_row<src1.rowsindex_row++)
    {
        for(int index_col=0; index_col<src1.colsindex_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
                dst.at<Vec3f>(index_rowindex_col)[index_c]=1-
                (1-src1.at<Vec3f>(index_rowindex_col)[index_c])/
                src2.at<Vec3f>(index_rowindex_col)[index_c];
        }
    }
}
线性加深
Linear_Burn
C=A+B-255
// 线性增强
void(Matsrc1Matsrc2Matdst)
{
    for(int index_row=0; index_row<src1.rowsindex_row++)
    {
        for(int index_col=0; index_col<src1.colsindex_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
                dst.at<Vec3f>(index_rowindex_col)[index_c]=max(
                src1.at<Vec3f>(index_rowindex_col)[index_c]+
                src2.at<Vec3f>(index_rowindex_col)[index_c]-1, (float)0.0);
        }
    }
}
变亮
C = MAX(A,B)
 
滤色
Screen

// Screen
void Screen(Mat& src1, Mat& src2, Mat& dst)
{
     for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
                dst.at<Vec3f>(index_row, index_col)[index_c]=1-
                         (1-src1.at<Vec3f>(index_row, index_col)[index_c])*
                         (1-src2.at<Vec3f>(index_row, index_col)[index_c]);
        }
    }
}
颜色减淡
Color_Dodge

// Color_Dodge 颜色减淡
void Color_Dodge(Mat& src1, Mat& src2, Mat& dst)
{
    for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
                dst.at<Vec3f>(index_row, index_col)[index_c]=
                          src2.at<Vec3f>(index_row, index_col)[index_c]/
                         (1-src1.at<Vec3f>(index_row, index_col)[index_c]);
        }
    }
}
线性减淡(添加)
C=A+B
// Lighten
void Lighten(Mat& src1, Mat& src2, Mat& dst)
{
    for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
                dst.at<Vec3f>(index_row, index_col)[index_c]=max(
                         src1.at<Vec3f>(index_row, index_col)[index_c],
                         src2.at<Vec3f>(index_row, index_col)[index_c]);
        }
    }
}
浅色  
叠加
Add_Color
// Add color
void Add_Color(Mat& src1, Mat& src2, Mat& dst)
{
    float a=0;
    float b=0;
     for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
            {
                a=src1.at<Vec3f>(index_row, index_col)[index_c];
                b=src2.at<Vec3f>(index_row, index_col)[index_c];
                if(b>0.5)
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=2*a*b;
                }
                else
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=1-2*(1-a)*(1-b);
                }
            }
        }
    }
}
柔光
Soft_Lighten
// Soft Lighten
void Soft_Lighten(Mat& src1, Mat& src2, Mat& dst)
{
    float a=0;
    float b=0;
     for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
            {
                a=src1.at<Vec3f>(index_row, index_col)[index_c];
                b=src2.at<Vec3f>(index_row, index_col)[index_c];
                if(a<=0.5)
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=(2*a-1)*(b-b*b)+b;
                }
                else
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=(2*a-1)*(sqrt(b)-b)+b;
                }
            }
        }
    }
}
强光
Strong_Lighten
void Strong_Lighten(Mat& src1, Mat& src2, Mat& dst)
{
    float a=0;
    float b=0;
     for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
            {
                a=src1.at<Vec3f>(index_row, index_col)[index_c];
                b=src2.at<Vec3f>(index_row, index_col)[index_c];
                if(a<=0.5)
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=2*a*b;
                }
                else
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=1-2*(1-a)*(1-b);
                }
            }
        }
    }
}
亮光
Vivid_Lighten
//Vivid Lighten
void Vivid_Lighten(Mat& src1, Mat& src2, Mat& dst)
{
    float a=0;
    float b=0;
     for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
            {
                a=src1.at<Vec3f>(index_row, index_col)[index_c];
                b=src2.at<Vec3f>(index_row, index_col)[index_c];
                if(a<=0.5)
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=1-(1-b)/(2*a);
                }
                else
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=b/(2*(1-a));
                }
            }
        }
    }
}
线性光
Linear_Lighten
// Linear Lighten
void Linear_Lighten(Mat& src1, Mat& src2, Mat& dst)
{
    dst=src2+2*src1-1;
}
点光
Pin_Lighten
// Pin lighten
void Pin_Lighten(Mat& src1, Mat& src2, Mat& dst)
{
    float a=0;
    float b=0;
     for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
            {
                a=src1.at<Vec3f>(index_row, index_col)[index_c];
                b=src2.at<Vec3f>(index_row, index_col)[index_c];
                if(b<=2*a-1)
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=2*a-1;
                }
                else if(b<=2*a)
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=b;
                }
                else
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=2*a;
                }
            }
        }
    }
}
实色混合
Hard_mix
// Hard mix
void Hard_mix(Mat& src1, Mat& src2, Mat& dst)
{
    float a=0;
    float b=0;
     for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
            {
                a=src1.at<Vec3f>(index_row, index_col)[index_c];
                b=src2.at<Vec3f>(index_row, index_col)[index_c];
                if(a<1-b)
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=0.0;
                }
                else
                {
                    dst.at<Vec3f>(index_row, index_col)[index_c]=1.0;
                }
            }
        }
    }
}
差值
Difference
// Difference
void Difference(Mat& src1, Mat& src2, Mat& dst)
{
    float a=0;
    float b=0;
     for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
            {
                a=src1.at<Vec3f>(index_row, index_col)[index_c];
                b=src2.at<Vec3f>(index_row, index_col)[index_c];
                dst.at<Vec3f>(index_row, index_col)[index_c]=abs(a-b);
            }
        }
    }
}
排除
Exclusion
// Exclusion
void Exclusion(Mat& src1, Mat& src2, Mat& dst)
{
    float a=0;
    float b=0;
     for(int index_row=0; index_row<src1.rows; index_row++)
    {
        for(int index_col=0; index_col<src1.cols; index_col++)
        {
            for(int index_c=0; index_c<3; index_c++)
            {
                a=src1.at<Vec3f>(index_row, index_col)[index_c];
                b=src2.at<Vec3f>(index_row, index_col)[index_c];
                dst.at<Vec3f>(index_row, index_col)[index_c]=a+b-2*a*b;
            }
        }
    }
}
减去  
划分
divide
结果色 = (基色 / 混合色) * 255
    Mat src = imread("t1.jpeg");
    src.convertTo(src,CV_32FC3,1.0/255);
    Mat gauss;
    Mat dst = src.clone();
    cv::GaussianBlur(src,gauss,Size(101,101),0);
    dst = src/gauss;

 

 

以上是关于photoshop图象/模式。的主要内容,如果未能解决你的问题,请参考以下文章

8Alpha通道和蒙版

ps中的位图,矢量图,颜色模式

Adobe Photoshop CC 2018绿色免激版

Serif Affinity Photo 1.9.0安装破解激活教程

Photoshop CC 2018 19.1.9 精简绿色便携版

Photoshop 基础一 安装