本文将介绍PS图层混合模式中比較复杂 的“明度”模式的算法原理及代码实现内容。
说到PS的图层混合模式,计算公式都有,详细代码实现也能找到,可是,都没有完整介绍全部图层混合模式的代码。比方“明度”模式。公式例如以下:
如果两张图的HSY颜色模式分别为: Hb,Sb,Yb---Hm,Sm,Ym
明度混合结果HSY = HbSbYm
这个公式非常easy,无非就是原图的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
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)
因此,依照上面的公式我们编码实现例如以下:
#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下载链接:点击打开链接

图像滤镜艺术---PS图层混合模式之明度模式的更多相关文章

  1. 图像滤镜艺术---PS图像转手绘特效实现方案

    原文:图像滤镜艺术---PS图像转手绘特效实现方案 手绘效果实现方案 本文介绍一种PS手绘效果的实现方案,PS步骤来自网络,本文介绍代码实现过程. 整体看来,虽然效果还是有很大差异,但是已经有了这种特 ...

  2. 图像滤镜艺术--PS平均(滤镜-模糊-平均)效果

    原文:图像滤镜艺术--PS平均(滤镜-模糊-平均)效果 本文介绍PS中滤镜-模糊-平均模糊的效果实现: 这个效果很简单,原理如下: 1,统计全图像素的R,G,B值得和sumR,sumG,sumB; 2 ...

  3. 图像滤镜艺术---流行艺术风滤镜特效PS实现

    原文:图像滤镜艺术---流行艺术风滤镜特效PS实现 今天,本人给大家介绍一款新滤镜:流行艺术风效果,先看下效果吧! 原图 流行艺术风效果图 上面的这款滤镜效果是不是很赞,呵呵,按照本人以往的逻辑,我会 ...

  4. 图像滤镜艺术---保留细节的磨皮滤镜之PS实现

    原文:图像滤镜艺术---保留细节的磨皮滤镜之PS实现 目前,对于人物照片磨皮滤镜,相信大家没用过也听过吧,这个滤镜的实现方法是多种多样,有难有简,有好有差,本人经过长时间的总结,得出了一种最简单,效果 ...

  5. 图像滤镜艺术---ZPhotoEngine超级算法库

    原文:图像滤镜艺术---ZPhotoEngine超级算法库 一直以来,都有个想法,想要做一个属于自己的图像算法库,这个想法,在经过了几个月的努力之后,终于诞生了,这就是ZPhotoEngine算法库. ...

  6. 图像滤镜艺术--编码基础(Photoshop基础变换的代码实现)

    原文:图像滤镜艺术--编码基础(Photoshop基础变换的代码实现) 自从上一篇博客写完之后,到现在已经有段时间了,这段时间不是不想接着写,只是想做的更好了在写出来给大家看呵呵. 今天,我将给大家介 ...

  7. 图像滤镜艺术--Toaster滤镜

    原文:图像滤镜艺术--Toaster滤镜     根据Instagram CEO的说法,Toaster滤镜是Instagram所有滤镜中最复杂的滤镜,这个滤镜给人一种新奇的红色烘烤感,很能让人联想起这 ...

  8. 图像滤镜艺术---Hudson滤镜(Instagram)

    原文:图像滤镜艺术---Hudson滤镜(Instagram)     今天给大家实现的是Instagram中的Hudson滤镜,为什么介绍Instagram滤镜,原因很简单,Instagram本身就 ...

  9. 图像滤镜艺术----Brannan滤镜

    原文:图像滤镜艺术----Brannan滤镜     作为第一篇文章,本人将介绍Instagram中Brannan 滤镜的实现过程,当然,是自己的模拟而已,结果差异敬请谅解.     先看下效果图: ...

随机推荐

  1. JS判断SharePoint页面编辑状态

    这篇博客主要讲使用不同的客户端方式来判断页面的编辑模式. 1.当页面处于发布状态时,可以使用下面两种方式:if(g_disableCheckoutInEditMode == true) {   ale ...

  2. CodeForces 232E.Quick Tortoise

    John Doe has a field, which is a rectangular table of size n × m. We assume that the field rows are ...

  3. c#.NET的事件与委托例子

    原文发布时间为:2008-07-25 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...

  4. 标准C程序设计七---76

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  5. declaration specifier, declarator, type specifier

    static struct abc * b; static struct abc : declaration specifier * b : declarator struct abc : type ...

  6. hdu4183往返经过至多每个点一次/最大流

    题意:从s到t,每个点有f值,只能从f值小的到大的,到T后回来,只能从f值大的到 小的,求可行否. 往返,其实就是俩条路过去(每个点最多一次),所以想到流量为2,跑最大流,看是否满2,又要每个点最多一 ...

  7. LeetCode OJ--Search for a Range

    http://oj.leetcode.com/problems/search-for-a-range/ 要求复杂度为O(lgn),用二分查找的思想. #include <iostream> ...

  8. SD-WAN用户实践分享:老网工趟出的SD-WAN成功路

    在这个离开“人大物云”(人-人工智能.大-大数据.物-物联网.云-云计算)话题都张不开嘴的年代,在这个在咖啡店谈生意都不好意思低于1个亿的年代,反思我的老本行——网络,正在以一种全新的.更加重要的姿态 ...

  9. FMDB支持的事务类型

    FMDB支持的事务类型   在数据库中,事务可以保证数据操作的完整性.当存在大量并发操作,容易出现死锁问题.在SQLite中,为了解决该问题,提供三种事务模式,分别为DEFFERED.IMMEDIAT ...

  10. mac 安装opencv-python

    Mac下安装opencv-python 项目中使用的是opencv 2的版本,因此下面说一下opencv2的一些安装流程. 安装方法 1:如果没有homebrew的话,需要先安装 安装命令: ruby ...