原文:图像滤镜艺术--编码基础(Photoshop基础变换的代码实现)
自从上一篇博客写完之后,到现在已经有段时间了,这段时间不是不想接着写,只是想做的更好了在写出来给大家看呵呵。
今天,我将给大家介绍制作图像滤镜的基础,也就是PS中的基本命令如何用代码实现,这里包括各种混合图层,去色命令,亮度对比度调整,饱和度调整以及曲线调整等,这些命令都是最基础的,如果我们掌握了这些知识,那么,一些复杂的滤镜也就有稳定的根基了。
1,混合图层
PS中,混合图层是制作滤镜的必需品,他包括了正常模式,溶解模式,变暗模式,正片叠底,颜色加深,线性加深,深色模式,变亮模式,滤色模式,颜色减淡,线性减淡,浅色模式,叠加模式,柔光模式,强光模式,亮光模式,线性光,点光,实色混合,插值模式,排除模式,减去模式,划分模式,色相,饱和度,颜色,明度等。
这些混合模式的原理及公示计算如下(来自网络总结):
正常模式:混合色*不透明度+(100%-混合色不透明度)*基色
溶解模式:溶解模式下混合色的不透明度及填充都是100%的话,我们就看不到基色图层。降低混合色图层的不透明度后,我们就会发现结果色中出现了很多细小的颗粒。这些颗粒会随着混合色的不透明度变化。不透明度越低混合色图层就被溶解的越多。剩下的部分就越少。不透明度越高混合色图层被溶解的部分就越少,剩下的部分就越多,结果色就越接近混合色。
变暗模式:变暗混合模式下,她会把混合色与基色进行对比,分别选择R,G,B三组数值中最小的数值,也就是最暗的颜色作为结果色的数值。这样整个画面会变得更暗,如果是彩色图像,颜色也会发生很大的改变。(位置互换不发生变化)
正片叠底:正片叠底混合原理:她是按照混合色与基色中的各R,G,B值计算,计算公式:结果色R=混合色R
* 基色R / 255,G值与B值同样的方法计算。最后得到的R,G,B值就是结果色的颜色。由于各通道的最大值是255,因此结果色的数值比混合色及基色的数值都要小,也就是结果色要暗。(位置互换不发生变化)
颜色加深:颜色加深可以快速增加图片的暗部。她的计算公式:结果色 =(基色
+ 混合色 - 255)* 255 /混合色。其中(基色 +混合色
- 255)如果出现负数就直接归0。因此在基色与混合色都较暗的时候都是直接变成黑色的。这样结果色的暗部就会增加。整体效果看上去对比较为强烈。
线性加深:线性加深的计算公式是:结果色 =基色 +混合色
- 255,如果基色 +混合色的数值小于255,结果色就为0。由这个公式可以看出,画面暗部会直接变成黑色。因此画面整体会更暗。白色与基色混合得到基色,黑色与基色混合得到黑色。(位置互换不发生变化)
深色模式:深色混合模式比较好理解。它是通过计算混合色与基色的所有通道的数值,然后选择数值较小的作为结果色。因此结果色只跟混合色或基色相同,不会产生出另外的颜色。白色与基色混合色得到基色,黑色与基色混合得到黑色。深色模式中,混合色与基色的数值是固定的,我们颠倒位置后,混合色出来的结果色是没有变化的。
变亮模式:变亮模式跟变暗模式是相对的,她是通过混合色与基色的相关数值进行比较,选择较大的数值作为结果色。因此结果色会更亮,同时颜色也会变化。(位置互换不发生变化)
滤色模式:滤色模式与正片叠底模式相对。她的计算公式是用:255 -混合色的补色
* 基色补色 / 255。得到的数据会比混合及基色更大,因此结果色会更亮。从计算公式也可以看出基色或混合色任何一项为255也就是白色,结果色数值就是255为白色。任何一项数值为0,也就是为黑色的话,结果色就跟数值不为0的一致。
颜色减淡:颜色减淡是通过混合色及基色的各通道颜色值进行对比,减少二者的对比度使基色的变亮来反映混合色。
她的计算公式:结果色 = 基色 + (混合色 * 基色) / (255 - 混合色)。混合色为黑色,结果色就等于基色,混合色为白色结果色就为白色。基色为黑色结果色就为黑色。
线性减淡:线性减淡是通过查看每个通道的颜色信息,并通过增加亮度使基色变亮以反映混合色。她的计算公式:结果色
= 基色 +混合色,其中基色与混合色的数值大于255,系统就默认为最大值也就是255。
由公式可以分析出混合色为黑色结果色就等于基色,混合色为白色结果色就为白色。基色也一样。我们颠倒混合色及基色的位置,结果色也不会变化。(位置互换不发生变化)
浅色模式:浅色模式比较好理解:她是通过计算混合色与基色所有通道的数值总和,哪个数值大就选为结果色。因此结果色只能在混合色与基色中选择,不会产生第三种颜色。与深色模式刚好相反。
叠加:叠加模式比较特别,她是通过分析基色个通道的数值,对颜色进行正片叠加或滤色混合,结果色保留基色的明暗对比。因此结果色以基色为主导。
计算公式:
基色 < = 128:结果色 =混合色
*基色 / 128;基色 > 128:结果色
= 255 - (255 -混合色)* (255 -基色)
/ 128。
从公式可以看出,结果色会根据基色的颜色数值选择不同的计算公式。
柔光模式:柔光模式是较为常用的模式,她是根据混合色的通道数值选择不同的公式计算混合色。数值大于128的时候,结果色就比基色稍亮;数值小于或等于128,结果色就比基色稍暗。柔光模式是以基色为主导,混合色只相应改变局部明暗。其中混合色为黑色,结果色不会为黑色,只比结果色稍暗,混合色为中性色,结果色跟基色一样。
计算公式:
混合色 <=128:结果色 =基色
+ (2 *混合色 - 255) * (基色 -基色
*基色 / 255) / 255;
混合色 >128:结果色
= 基色 + (2 *混合色 - 255) * (Sqrt(基色/255)*255
-基色)/255。
强光模式:强光模式跟叠加模式十分类似,只是在计算的时候需要通过混合色来控制,混合色的数值小于或等于128的时候,颜色会变暗;混合色的数值大于128的时候,颜色会变亮。混合色为白色,结果色就为白色;混合色为黑色,结果为黑色。混合色起到主导作用。
计算公式:
混合色 <= 128:结果色 =混合色
*基色 / 128;
混合色 > 128:结果色 = 255 -(255
-混合色) * (255 -基色) / 128.
亮光模式:亮光模式是通过增加或减少对比度是颜色变暗或变亮,具体取决于混合色的数值。混合色比中性灰色暗,结果色就相应的变暗,混合色比中性灰色亮,结果色就相应的变亮。有点类似颜色加深或颜色减淡。
计算公式:
A---基色;B—混合色
C=A-(255-A)*(255-2B)/2B 当混合色>128时
C=A+[A*(2B-255)]/[255-(2B-255)
线性光:线性光:通过减少或增加亮度,来使颜色加深或减淡。具体取决于混合色的数值。混合色数值比中性灰色暗的时候进行相应的加深混合;混合色的数值比中性灰色亮的时候进行减淡混合。这里的加深及减淡时线性加深或线性减淡。
计算公式:结果色 = 2 *混合色
+基色 -255。数值大于255取255。
点光:点光模式:她会根据混合色的颜色数值替换相应的颜色。如果混合色数值小于中性灰色,那么就替换比混合色亮的像素;相反混合色的数值大于中性灰色,则替换比混合色暗的像素。因此混合出来的颜色对比较大。
计算公式:
基色 < 2 *混合色 - 255:结果色
= 2 *混合色 - 255;
2 * 混合色 - 255 <基色
< 2 *混合色:结果色 =基色;
基色 > 2 *混合色:结果色 = 2 *混合色。
实色混合:实色混合是把混合色颜色中的红、绿、蓝通道数值,添加到基色的RGB值中。结果色的R、G、B通道的数值只能是255或0。因此结构色只有一下八种可能:红、绿、蓝、黄、青、洋红、白、黑。由此看以看出结果色是非常纯的颜色。
计算公式:
混合色+ 基色 < 255:结果色 = 0 ;混合色 + 基色 >= 255:结果色= 255。
差值模式:差值模式:查看每个通道的数值,用基色减去混合色或用混合色减去基色。具体取决于混合色与基色那个通道的数值更大。白色与任何颜色混合得到反相色,黑色与任何颜色混合颜色不变。
计算公式:
结果色 =绝对值(混合色 -基色)
排除模式:排除模式是跟差值模式非常类似的混合模式,只是排除模式的结果色对比度没有差值模式强。白色与基色混合得到基色补色,黑色与基色混合得到基色。
计算公式:
结果色 = (混合色 +基色)
-混合色 *基色 / 128。
减去模式:减去模式:查看各通道的颜色信息,并从基色中减去混合色。如果出现负数就剪切为零。与基色相同的颜色混合得到黑色;白色与基色混合得到黑色;黑色与基色混合得到基色。
计算公式:
结果色 =基色 -混合色。
划分模式:划分模式:超看每个通道的颜色信息,并用基色分割混合色。基色数值大于或等于混合色数值,混合出的颜色为白色。基色数值小于混合色,结果色比基色更暗。因此结果色对比非常强。白色与基色混合得到基色,黑色与基色混合得到白色。
计算公式:
结果色 = (基色 /混合色)
* 255。
色相:色相混合模式:结果色保留混合色的色相,饱和度及明度数值保留明度数值。这里用到的色相、饱和度、明度也是一种颜色模式,也称作:HSB模式。色相代表颜色的颜色相貌,也就是我们看到的红、绿、蓝等;饱和度是颜色的饱和程度,也就是鲜艳度;明度是颜色的明暗程度。其中黑色、灰色、白色是没有颜色和饱和度的,也就是相关数值为0。
饱和度模式:饱和度模式是用混合色的饱和度以及基色的色相和明度创建结果色。我们都知道饱和度只控制颜色的鲜艳程度,因此混合色只改变图片的鲜艳度,不能影响颜色。黑、白、灰除外,因为这些颜色的饱和度为0,混合后只能产生一种灰色效果。
颜色模式:颜色模式是用混合色的色相,饱和度以及基色的明度创建结果色。这种模式下混合色控制真个画面的颜色,是黑白图片上色的绝佳模式,因为这种模式下会保留基色图片也就是黑白图片的明度度。黑、白、会与基色混合会产生相同的灰色效果,因为这三种颜色的色相,饱和度都是0。
明度模式:明度混合模式是利用混合色的明度以及基色的色相与饱和度创建结果色。她跟颜色模式刚好相反,因此混合色图片只能影响图片的明暗度,不能对基色的颜色产生影响,黑、白、灰除外。黑色与基色混合得到黑色;白色与基色混合得到白色;灰色与基色混合得到明暗不同的基色。
2,去色命令
PS里的去色命令:每个像素R、G、B三个值中最大值和最小值和的一半,作为最后灰度值输出;
3,亮度对比度命令
对于零度对比度命令,网络中介绍的最详细的是这个博客链接,我就不在重述了 http://blog.csdn.net/maozefa/article/details/1776824
4,饱和度命令
对于饱和度、色相命令,网络中介绍最详细的是这个博客链接, http://blog.csdn.net/maozefa/article/details/8461849
5,曲线命令
曲线命令看起来比较复杂,实际上只是几个参数而已,网络中详细介绍的链接:http://blog.csdn.net/laviewpbt/article/details/17162849
以上是我们只做一款优秀滤镜比不可少的知识,言归正传,今天我主要给大家提供一个C#/C的DEMO,代码中实现了以上基本功能,大家可以理解知识之后自己编码,也可以直接使用我的DEMO中的库(SpecialEffect.dll),或者是C#的SpecialEffectClass.cs,简单放上一些调用代码:
public static Bitmap DoLevelAdjust(Bitmap srcBitmap, int DestChannel, int InputLeftLimit, int InputMiddle, int InputRightLimit, int OutputLeftLimit, int OutputRightLimit, int pxMode)
{
Bitmap src = new Bitmap(srcBitmap);
int w = src.Width;
int h = src.Height;
PixelFormat format = (pxMode == 0 ? PixelFormat.Format24bppRgb : PixelFormat.Format32bppArgb);
BitmapData srcData = src.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, format);
LevelAdjust((byte*)srcData.Scan0, w, h, srcData.Stride, DestChannel, InputLeftLimit, InputMiddle, InputRightLimit, OutputLeftLimit, OutputRightLimit,pxMode);
src.UnlockBits(srcData);
return src;
}
public static Bitmap DoSaturationAdjust(Bitmap srcBitmap, int pxMode,int saturation)
{
Bitmap src = new Bitmap(srcBitmap);
int w = src.Width;
int h = src.Height;
PixelFormat format = (pxMode == 0 ? PixelFormat.Format24bppRgb : PixelFormat.Format32bppArgb);
BitmapData srcData = src.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, format);
SaturationProcess((byte*)srcData.Scan0, w, h, srcData.Stride, pxMode,saturation);
src.UnlockBits(srcData);
return src;
}
public static Bitmap DoBrightContrastAdjust(Bitmap srcBitmap, int pxMode, int brightness,int contrast,int threshold)
{
Bitmap src = new Bitmap(srcBitmap);
int w = src.Width;
int h = src.Height;
PixelFormat format = (pxMode == 0 ? PixelFormat.Format24bppRgb : PixelFormat.Format32bppArgb);
BitmapData srcData = src.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, format);
BrightContrastProcess((byte*)srcData.Scan0, w, h, srcData.Stride, pxMode, brightness, contrast, threshold);
src.UnlockBits(srcData);
return src;
}
public static Bitmap DoGrayEffect(Bitmap srcBitmap, int pxMode)
{
Bitmap src = new Bitmap(srcBitmap);
int w = src.Width;
int h = src.Height;
PixelFormat format = (pxMode == 0 ? PixelFormat.Format24bppRgb : PixelFormat.Format32bppArgb);
BitmapData srcData = src.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, format);
Desaturate((byte*)srcData.Scan0, w, h, srcData.Stride, pxMode);
src.UnlockBits(srcData);
return src;
}
DEMO的界面如下:
最后,给出这个DEMO的免费下载链接:http://download.csdn.net/detail/trent1985/8131703
如果大家有什么不理解的问题,可以邮箱联系dongtingyueh@163.com,或者QQ:1358009172