图像滤镜艺术---PS图层混合模式之明度模式
来源:互联网 发布:灭罪师类似的网络剧 编辑:程序博客网 时间:2024/06/10 12:21
图像滤镜艺术---PS图层混合模式之明度模式
本文将介绍PS图层混合模式中比较复杂 的“明度”模式的算法原理及代码实现内容。
说到PS的图层混合模式,计算公式都有,具体代码实现也能找到,但是,都没有完整介绍所有图层混合模式的代码,比如“明度”模式,公式如下:
假设两张图的HSY颜色模式分别为: Hb,Sb,Yb---Hm,Sm,Ym
明度混合结果HSY = HbSbYm
这个公式很简单,无非就是原图的H,S分量+混合图的Y分量而已,但是具体代码如何实现,却很少有人分享,今天,我将给大家分享本人的代码。
HSY模式是一种彩色传输模型,传输基本的色差和亮度信号。如果直接使用HSY颜色空间,这个颜色空间好像很少见,具体HSY计算公式如下:
Y = 0.299R + 0.587G + 0.114B;
Cr = R - Y;
Cb = B - Y;
H = arctan(Cr/Cb);
S = sqrt(Cr * Cr + Cb * Cb);
大家可以看到,这个公式中运算复杂,但是是基于Cr, Cb分量计算的,而且,明度图层混合模式结果中实际上只改变了Y分量,因此,我们这里可以使用YCbCr颜色空间来代替HSY颜色空间实现这个功能。
YCbCr与RGB转换公式如下:
Y = 0.257*R+0.564*G+0.098*B+16
Cb = -0.148*R-0.291*G+0.439*B+128
Cr = 0.439*R-0.368*G-0.071*B+128
Cb = -0.148*R-0.291*G+0.439*B+128
Cr = 0.439*R-0.368*G-0.071*B+128
R = 1.164*(Y-16)+1.596*(Cr-128)
G = 1.164*(Y-16)-0.392*(Cb-128)-0.813*(Cr-128)
B = 1.164*(Y-16)+2.017*(Cb-128)
G = 1.164*(Y-16)-0.392*(Cb-128)-0.813*(Cr-128)
B = 1.164*(Y-16)+2.017*(Cb-128)
因此,按照上面的公式我们编码实现如下:
#include"TRGB2YCbCr.h"#include <stdlib.h>#include <stdio.h>#include "math.h"#include <string.h>const float YCbCrYRF = 0.299F; // RGB转YCbCr的系数(浮点类型)const float YCbCrYGF = 0.587F;const float YCbCrYBF = 0.114F;const float YCbCrCbRF = -0.168736F;const float YCbCrCbGF = -0.331264F;const float YCbCrCbBF = 0.500000F;const float YCbCrCrRF = 0.500000F;const float YCbCrCrGF = -0.418688F;const float YCbCrCrBF = -0.081312F;const float RGBRYF = 1.00000F; // YCbCr转RGB的系数(浮点类型)const float RGBRCbF = 0.0000F;const float RGBRCrF = 1.40200F;const float RGBGYF = 1.00000F;const float RGBGCbF = -0.34414F;const float RGBGCrF = -0.71414F;const float RGBBYF = 1.00000F;const float RGBBCbF = 1.77200F;const float RGBBCrF = 0.00000F;const int Shift = 20;const int HalfShiftValue = 1 << (Shift - 1);const int YCbCrYRI = (int)(YCbCrYRF * (1 << Shift) + 0.5); // RGB转YCbCr的系数(整数类型)const int YCbCrYGI = (int)(YCbCrYGF * (1 << Shift) + 0.5);const int YCbCrYBI = (int)(YCbCrYBF * (1 << Shift) + 0.5);const int YCbCrCbRI = (int)(YCbCrCbRF * (1 << Shift) + 0.5);const int YCbCrCbGI = (int)(YCbCrCbGF * (1 << Shift) + 0.5);const int YCbCrCbBI = (int)(YCbCrCbBF * (1 << Shift) + 0.5);const int YCbCrCrRI = (int)(YCbCrCrRF * (1 << Shift) + 0.5);const int YCbCrCrGI = (int)(YCbCrCrGF * (1 << Shift) + 0.5);const int YCbCrCrBI = (int)(YCbCrCrBF * (1 << Shift) + 0.5);const int RGBRYI = (int)(RGBRYF * (1 << Shift) + 0.5); // YCbCr转RGB的系数(整数类型)const int RGBRCbI = (int)(RGBRCbF * (1 << Shift) + 0.5);const int RGBRCrI = (int)(RGBRCrF * (1 << Shift) + 0.5);const int RGBGYI = (int)(RGBGYF * (1 << Shift) + 0.5);const int RGBGCbI = (int)(RGBGCbF * (1 << Shift) + 0.5);const int RGBGCrI = (int)(RGBGCrF * (1 << Shift) + 0.5);const int RGBBYI = (int)(RGBBYF * (1 << Shift) + 0.5);const int RGBBCbI = (int)(RGBBCbF * (1 << Shift) + 0.5);const int RGBBCrI = (int)(RGBBCrF * (1 << Shift) + 0.5);void RGBToYCbCr(int R, int G, int B, int*Y,int*Cb, int* Cr){*Y = ((YCbCrYRI * R + YCbCrYGI * G + YCbCrYBI * B + HalfShiftValue) >> Shift); *Cb = (128 + ((YCbCrCbRI * R + YCbCrCbGI * G + YCbCrCbBI * B + HalfShiftValue) >> Shift)); *Cr = (128 + ((YCbCrCrRI * R + YCbCrCrGI * G + YCbCrCrBI * B + HalfShiftValue) >> Shift));}void YCbCrToRGB(int Y, int Cb, int Cr, int*R,int*G, int* B){ Cb = Cb - 128; Cr = Cr - 128; *R = Y + ((RGBRCrI * Cr + HalfShiftValue) >> Shift); *G = Y + ((RGBGCbI * Cb + RGBGCrI * Cr + HalfShiftValue) >> Shift); *B = Y + ((RGBBCbI * Cb + HalfShiftValue) >> Shift); if (*R > 255) *R = 255; else if (*R < 0) *R = 0; if (*G > 255) *G = 255; else if (*G < 0) *G = 0; if (*B > 255) *B = 255; else if (*B < 0) *B = 0;}int ColorBlendModeBrightness(unsigned char* baseData, unsigned char* mixData, int width, int height, int stride){int i, j, pos;int bY, bCb, bCr, mY, mCb, mCr, br, bg, bb, mr, mg, mb;unsigned char* pBase = baseData;unsigned char* pMix = mixData;int offset = stride - width * 4;for(j = 0; j < height; j++){for(i = 0; i < width; i++){bb = pBase[0];bg = pBase[1];br = pBase[2];mb = pMix[0];mg = pMix[1];mr = pMix[2];RGBToYCbCr(mr,mg,mb,&mY,&mCb,&mCr);RGBToYCbCr(br,bg,bb,&bY,&bCb,&bCr);YCbCrToRGB((mY+bY)/2, bCb, bCr, &br,&bg,&bb);//(mY+bY)/2表示透明度为50%pBase[0] = bb;pBase[1] = bg;pBase[2] = br;pBase += 4;pMix += 4;}pBase += offset;pMix += offset;}return 0;}
这个就是所有编码了,而且这个颜色空间转换的代码已经经过优化,大家可以直接使用,下面我给出效果图(该效果是按照明度图层混合模式50%透明度设置得到的):
大家可以看到,效果图和PS的效果图几乎一致,最后,给出一个DEMO下载链接:点击打开链接
0 0
- 图像滤镜艺术---PS图层混合模式之明度模式
- 图像滤镜艺术---PS图层混合模式之明度模式
- 图像特效---PS图层混合模式之明度模式
- 图像特效---PS图层混合模式之明度模式
- ps图层混合模式
- PS图层混合模式
- Photoshop PS图层混合模式详解
- PS图层混合模式中英文对照
- PS图层混合模式详解
- 解读各种PS图层混合模式的工作原理
- 图像滤镜艺术---流行艺术风滤镜特效PS实现
- OpenLayers 之 地图图层数据来源(ol.source)详解,ps图层混合模式详解
- 如何使用OPENCV实现两张图片的混合(PS中的图层不透明度)
- 图像滤镜艺术---PS引擎库发布
- 图像滤镜艺术---保留细节的磨皮滤镜之PS实现
- 图像(层)正常混合模式详解
- 图像滤镜艺术--PS平均(滤镜-模糊-平均)效果
- ps混合模式算法
- spring
- java动态代理(JDK和cglib)
- jQuery操作select的实例代码
- 使用fuel6.0自动安装openstack-juno版本(2)
- 安卓009SQLite数据库
- 图像滤镜艺术---PS图层混合模式之明度模式
- mysqldump
- cocodata有一个版本迭代
- 【bzoj3790】【神奇项链】【manacher+dp+树状数组】
- theano提示:g++ not detected的解决办法
- Java LinkedList特有方法
- 数据库中事务的使用
- Qt QLineEdit 根据拉伸宽度自动加省略点
- ScrollView嵌套ListView高度计算