图像滤镜艺术---PS图层混合模式之明度模式
生活随笔
收集整理的這篇文章主要介紹了
图像滤镜艺术---PS图层混合模式之明度模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
圖像濾鏡藝術---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下載鏈接:點擊打開鏈接
本文將介紹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下載鏈接:點擊打開鏈接
總結
以上是生活随笔為你收集整理的图像滤镜艺术---PS图层混合模式之明度模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网格分割算法(Random Walks)
- 下一篇: libsvm Minist Hog 手写