图像滤镜艺术---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

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下载链接:点击打开链接
时间: 2024-10-19 13:21:18

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

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

手绘效果实现方案 本文介绍一种PS手绘效果的实现方案,PS步骤来自网络,本文介绍代码实现过程. 整体看来,虽然效果还是有很大差异,但是已经有了这种特效的风格了,毕竟PS效果图中关于头发的部分是人工手动涂抹实现的,这一点,程序是无法自动实现的,这一点还需要大家理解. 本人实现的算法流程如下: 大家可以对照一下看看. 这里贴出图像转手绘效果的PS实现教程,这个教程如下(如果图片无法显示,请看点击打开链接): 先看效果: 原图 最终效果及局部细节 眼睛的处理,大家可以参考这篇教程:http://wei

图像滤镜艺术---PS引擎库发布

为了方便大家用PS实现漂亮的滤镜,然后转换为相应的代码实现,本人发布PS引擎库ZPhotoEngine 4.0的SDK完整版. 这个SDK中包含了大部分的PS基础算法: 对比度亮度调节(包含PS中的线性和非线性的对比度亮度调节) 饱和度色相明度调节 曲线调节 色阶调节 色彩平衡 通道混合器 自动对比度 自动色阶 USM 高反差保留 去色 直方图均衡化 过度曝光 黑白 阈值 查找边缘 表面模糊 高斯模糊 中间值 色温调节 背景虚化 图层混合算法 浮雕 马赛克 动感模糊 ...... 大部分算法与P

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

一直以来,都有个想法,想要做一个属于自己的图像算法库,这个想法,在经过了几个月的努力之后,终于诞生了,这就是ZPhotoEngine算法库. 这个算法库目前包含两个模块:基础图像算法模块+滤镜模块,使用C语言实现,现在免费分享给大家,可以适用于PC/Android/Ios三大平台. 1,基础图像算法模块 这个模块,本人以Photoshop基础算法为原形,模拟出了PS大部分的基础算法. 为什么选择Photoshop算法?这个也是我的算法库一个优势,目前开源算法库多如牦牛,但是,能和PS媲美的,少之

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

今天,本人给大家介绍一款新滤镜:流行艺术风效果,先看下效果吧! 原图 流行艺术风效果图 上面的这款滤镜效果是不是很赞,呵呵,按照别人以往的逻辑,我会先介绍PS实现过程,然后,在下一篇博客中将介绍完整的C#代码实现,并附上程序DEMO给大家分享! 现在开始PS过程: 1,打开图像,复制两份图层A,B: 2,将B图层隐藏,对图层A执行: 反相操作-"明度"图层混合-透明度"50%" 如图所示: 3,可见B图层,对B执行: 阈值(128)-"正片叠底"

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

目前,对于人物照片磨皮滤镜,相信大家没用过也听过吧,这个滤镜的实现方法是多种多样,有难有简,有好有差,本人经过长时间的总结,得出了一种最简单,效果又不失细节与真实感的方法,对于这个方法,本人将先介绍它的PS实现,在下一篇博客中,我们将具体介绍它的C#代码实现. PS实现过程如下: 1,打开人物图像,复制图层,命名为"HighPass": 2,对HighPass执行"滤镜-表面模糊",半径-15即可,这里可以根据具体图像,适当调整半径大小: 3,复制原始图层,命名为&

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

自从上一篇博客写完之后,到现在已经有段时间了,这段时间不是不想接着写,只是想做的更好了在写出来给大家看呵呵. 今天,我将给大家介绍制作图像滤镜的基础,也就是PS中的基本命令如何用代码实现,这里包括各种混合图层,去色命令,亮度对比度调整,饱和度调整以及曲线调整等,这些命令都是最基础的,如果我们掌握了这些知识,那么,一些复杂的滤镜也就有稳定的根基了. 1,混合图层 PS中,混合图层是制作滤镜的必需品,他包括了正常模式,溶解模式,变暗模式,正片叠底,颜色加深,线性加深,深色模式,变亮模式,滤色模式,颜

图像滤镜艺术---乐高像素拼图特效

本文介绍乐高像素拼图特效滤镜的实现,这里仅仅介绍PS实现过程,关于程序的实现,大家可以使用ZPhotoEngine来实现,这个引擎可以在www.zealpixel.com上下载,是免费的. 现在介绍PS的实现过程: 1,打开一张美丽的图像: 原图 复制图层,命名为"马赛克",然后对该图层执行"滤镜-像素化-马赛克-20": 2,复制"马赛克"图层,命名为"马赛克副本": 3,对马赛克副本图层执行"调整-色调分离-4&

图像滤镜艺术--Toaster滤镜

根据Instagram CEO的说法,Toaster滤镜是Instagram所有滤镜中最复杂的滤镜,这个滤镜给人一种新奇的红色烘烤感,很能让人联想起这个Toaster单词的本意呵呵,今天我将用C#实现这个滤镜,当然我也只是探索,如何逼近它的效果,差异的存在在所难免,大家勿怪哦. 按照之前的说法,还是先使用Photoshop进行模拟,然后根据模拟步骤,进行C#代码编写. 首先,看下效果图: (a)PS效果图 (b)Instagram效果图 (c)C#代码效果图 效果怎么样我说了不算呵呵,下面介绍P

图像滤镜艺术---保留细节的磨皮之C#程序实现

上一篇博文"保留细节的磨皮滤镜之PS实现"一文中.我简介了本人自己总结的一种非常easy的磨皮滤镜,这个滤镜在磨光皮肤的同一时候,会保留非常不错的细节,今天,我将介绍使用C#程序实现这个磨皮的过程. 这里,我们相同是使用ZPhotoEngine库来实现,毕竟这个库中实现的效果跟PS是差点儿一模一样的.关于下载地址,文章最后会给出.废话不多说了,磨皮过程例如以下: 一.对原图的副本a运行表面模糊,半径15: 二.对原图运行高反差保留,半径1.0. 三.对高反差结果与原图做线性光图层处理,