影象演算法 -- 最全混合圖層演算法(附原始碼)
混合圖層演算法
本文中的混合圖層跟PhotoShop中完全一致。
1正常模式:混合色*不透明度+(100%-混合色不透明度)
2溶解模式:溶解模式下混合色的不透明度及填充都是100%的話,我們就看不到基色圖層。降低混合色圖層的不透明度後,我們就會發現結果色中出現了很多細小的顆粒。這些顆粒會隨著混合色的不透明度變化。不透明度越低混合色圖層就被溶解的越多。剩下的部分就越少。不透明度越高混合色圖層被溶解的部分就越少,剩下的部分就越多,結果色就越接近混合色。
3變暗模式:變暗混合模式下,它會把混合色與基色進行對比,分別選擇R,G,B三組數值中最小的數值,也就是最暗的顏色作為結果色的數值。這樣整個畫面會變得更暗,如果是彩色影象,顏色也會發生很大的改變。(位置互換不發生變化)
4正片疊底:正片疊底混合原理:它是按照混合色與基色中的各R,G,B值計算,計算公式:結果色R=混合色R * 基色R / 255,G值與B值同樣的方法計算。最後得到的R,G,B值就是結果色的顏色。由於各通道的最大值是255,因此結果色的數值比混合色及基色的數值都要小,也就是結果色要暗。(位置互換不發生變化)
5顏色加深:顏色加深可以快速增加圖片的暗部。它的計算公式:結果色 = (基色 + 混合色 - 255)* 255 / 混合色。其中(基色 + 混合色 - 255)如果出現負數就直接歸0。因此在基色與混合色都較暗的時候都是直接變成黑色的。這樣結果色的暗部就會增加。整體效果看上去對比較為強烈。
6線性加深:線性加深的計算公式是:結果色 = 基色 + 混合色 - 255,如果基色 + 混合色的數值小於255,結果色就為0。由這個公式可以看出,畫面暗部會直接變成黑色。因此畫面整體會更暗。白色與基色混合得到基色,黑色與基色混合得到黑色。(位置互換不發生變化)
7深色模式:深色混合模式比較好理解。它是通過計算混合色與基色的所有通道的數值,然後選擇數值較小的作為結果色。因此結果色只跟混合色或基色相同,不會產生出另外的顏色。白色與基色混合色得到基色,黑色與基色混合得到黑色。深色模式中,混合色與基色的數值是固定的,我們顛倒位置後,混合色出來的結果色是沒有變化的。
8變亮模式:變亮模式跟變暗模式是相對的,它是通過混合色與基色的相關數值進行比較,選擇較大的數值作為結果色。因此結果色會更亮,同時顏色也會變化。(位置互換不發生變化)
9濾色模式:濾色模式與正片疊底模式相對。它的計算公式是:
255 - 混合色的補色 * 基色補色 / 255。得到的資料會比混合及基色更大,因此結果色會更亮。從計算公式也可以看出基色或混合色任何一項為255也就是白色,結果色數值就是255為白色。任何一項數值為0,也就是為黑色的話,結果色就跟數值不為0的一致。
10顏色減淡:顏色減淡是通過混合色及基色的各通道顏色值進行對比,減少二者的對比度使基色的變亮來反映混合色。
它的計算公式:結果色 = 基色 + (混合色 * 基色)
/ (255 - 混合色)。混合色為黑色,結果色就等於基色,混合色為白色結果色就為白色。基色為黑色結果色就為黑色。
11線性減淡:線性減淡是通過檢視每個通道的顏色資訊,並通過增加亮度使基色變亮以反映混合色。它的計算公式:結果色 = 基色 + 混合色,其中基色與混合色的數值大於255,系統就預設為最大值也就是255。
由公式可以分析出混合色為黑色結果色就等於基色,混合色為白色結果色就為白色。基色也一樣。我們顛倒混合色及基色的位置,結果色也不會變化。(位置互換不發生變化)
12淺色模式:淺色模式比較好理解:它是通過計算混合色與基色所有通道的數值總和,哪個數值大就選為結果色。因此結果色只能在混合色與基色中選擇,不會產生第三種顏色。與深色模式剛好相反。
13疊加:疊加模式比較特別,它是通過分析基色個通道的數值,對顏色進行正片疊加或濾色混合,結果色保留基色的明暗對比,因此結果色以基色為主導。
計算公式:
基色 < = 128:結果色 = 混合色 * 基色 /
128;基色 > 128:結果色 = 255 - (255
- 混合色)* (255 - 基色) / 128。
從公式可以看出,結果色會根據基色的顏色數值選擇不同的計算公式。
14柔光模式:柔光模式是較為常用的模式,它是根據混合色的通道數值選擇不同的公式計算混合色。數值大於128的時候,結果色就比基色稍亮;數值小於或等於128,結果色就比基色稍暗。柔光模式是以基色為主導,混合色只相應改變區域性明暗。其中混合色為黑色,結果色不會為黑色,只比結果色稍暗,混合色為中性色,結果色跟基色一樣。
計算公式:
混合色 <=128:結果色 = 基色 +
(2 * 混合色 - 255) * (基色 - 基色 * 基色 /
255) / 255;
混合色 >128: 結果色 = 基色 +
(2 * 混合色 - 255) * (Sqrt(基色/255)*255 - 基色)/255。
如果基色=混合色,則可優化為256的表smoothlight,公式變形如下:
res = x + (2x-255)*(x-x*x/255)/255;
res = x+(2x-255)*(255*sqrt(x/255)-x)/255;
unsigned char smoothlight[256] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 15, 16, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 53, 54, 55, 56, 58, 59, 60, 62, 63, 64, 66, 67, 68, 70, 71, 72, 74, 75, 77, 78, 79, 81, 82, 84, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105, 107, 108, 110, 111, 113, 114, 116, 117, 119, 120, 122, 123, 125, 126, 128, 129, 131, 132, 133, 135, 136, 137, 139, 140, 142, 143, 144, 146, 147, 148, 150, 151, 152, 154, 155, 156, 158, 159, 160, 161, 163, 164, 165, 166, 168, 169, 170, 171, 173, 174, 175, 176, 178, 179, 180, 181, 182, 183, 185, 186, 187, 188, 189, 190, 191, 192, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 222, 223, 224, 225, 226, 227, 228, 228, 229, 230, 231, 232, 233, 233, 234, 235, 236, 236, 237, 238, 239, 239, 240, 241, 241, 242, 243, 243, 244, 245, 245, 246, 247, 247, 248, 248, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 255};
15強光模式:強光模式跟疊加模式十分類似,只是在計算的時候需要通過混合色來控制,混合色的數值小於或等於128的時候,顏色會變暗;混合色的數值大於128的時候,顏色會變亮。混合色為白色,結果色就為白色;混合色為黑色,結果為黑色。混合色起到主導作用。
計算公式:
混合色 <= 128:結果色 = 混合色 * 基色 /
128;
混合色 > 128 :結果色 = 255 - (255
- 混合色) * (255 - 基色) / 128.
16亮光模式:亮光模式是通過增加或減少對比度是顏色變暗或變亮,具體取決於混合色的數值。混合色比中性灰色暗,結果色就相應的變暗,混合色比中性灰色亮,結果色就相應的變亮。有點類似顏色加深或顏色減淡。
計算公式:
A---基色;B—混合色
C=A-(255-A)*(255-2B)/2B 當混合色>128時
C=A+[A*(2B-255)]/[255-(2B-255)
17線性光:線性光:通過減少或增加亮度,來使顏色加深或減淡。具體取決於混合色的數值。混合色數值比中性灰色暗的時候進行相應的加深混合;混合色的數值比中性灰色亮的時候進行減淡混合。這裡的加深及減淡時線性加深或線性減淡。
計算公式:結果色 = 2 * 混合色 + 基色 -255。數值大於255取255。
18點光:點光模式:它會根據混合色的顏色數值替換相應的顏色。如果混合色數值小於中性灰色,那麼就替換比混合色亮的畫素;相反混合色的數值大於中性灰色,則替換比混合色暗的畫素,因此混合出來的顏色對比較大。
計算公式:
基色 < 2 * 混合色 - 255:結果色 =
2 * 混合色 - 255;
2 * 混合色 - 255 < 基色 <
2 * 混合色 :結果色 = 基色;
基色 > 2 * 混合色:結果色 = 2 * 混合色。
19實色混合: 實色混合是把混合色顏色中的紅、綠、藍通道數值,新增到基色的RGB值中。結果色的R、G、B通道的數值只能是255或0。因此結構色只有一下八種可能:紅、綠、藍、黃、青、洋紅、白、黑。由此看以看出結果色是非常純的顏色。
計算公式:
混合色 + 基色 < 255:結果色 = 0 ;混合色 + 基色 >= 255:結果色 = 255。
20差值模式:差值模式:檢視每個通道的數值,用基色減去混合色或用混合色減去基色。具體取決於混合色與基色那個通道的數值更大。白色與任何顏色混合得到反相色,黑色與任何顏色混合顏色不變。
計算公式:
結果色 = 絕對值(混合色 - 基色)
21排除模式:排除模式是跟差值模式非常類似的混合模式,只是排除模式的結果色對比度沒有差值模式強。白色與基色混合得到基色補色,黑色與基色混合得到基色。
計算公式:
結果色 = (混合色 + 基色)
- 混合色 * 基色 / 128。
22減去模式:減去模式:檢視各通道的顏色資訊,並從基色中減去混合色。如果出現負數就剪下為零;與基色相同的顏色混合得到黑色;白色與基色混合得到黑色;黑色與基色混合得到基色。
計算公式:
結果色 = 基色 - 混合色。
23劃分模式:檢視每個通道的顏色資訊,並用基色分割混合色。基色數值大於或等於混合色數值,混合出的顏色為白色。基色數值小於混合色,結果色比基色更暗。因此結果色對比非常強。白色與基色混合得到基色,黑色與基色混合得到白色。
計算公式:
結果色 = (基色 / 混合色)
* 255。
24色相:色相混合模式:結果色保留混合色的色相,飽和度及明度數值保留明度數值。這裡用到的色相、飽和度、明度也是一種顏色模式,也稱作:HSB模式。色相代表顏色的顏色相貌,也就是我們看到的紅、綠、藍等;飽和度是顏色的飽和程度,也就是鮮豔度;明度是顏色的明暗程度。其中黑色、灰色、白色是沒有顏色和飽和度的,也就是相關數值為0。
25飽和度模式:飽和度模式是用混合色的飽和度以及基色的色相和明度建立結果色。我們都知道飽和度只控制顏色的鮮豔程度,因此混合色只改變圖片的鮮豔度,不能影響顏色。黑、白、灰除外,因為這些顏色的飽和度為0,混合後只能產生一種灰色效果。
26顏色模式:顏色模式是用混合色的色相,飽和度以及基色的明度建立結果色。這種模式下混合色控制真個畫面的顏色,是黑白圖片上色的絕佳模式,因為這種模式下會保留基色圖片也就是黑白圖片的明度度。黑、白、會與基色混合會產生相同的灰色效果,因為這三種顏色的色相,飽和度都是0。
27明度模式:明度混合模式是利用混合色的明度以及基色的色相與飽和度建立結果色。她跟顏色模式剛好相反,因此混合色圖片只能影響圖片的明暗度,不能對基色的顏色產生影響,黑、白、灰除外。黑色與基色混合得到黑色;白色與基色混合得到白色;灰色與基色混合得到明暗不同的基色。
28去色公式:每個畫素RGB的最大值和最小值和的一半,作為最後值輸出。
附錄 Android C Code with RGB565
附錄 Android C Code with RGB565
specialeffect.h
#ifndef SPECIALEFFECT
#define SPECIALEFFECT
#include
#include
#include
#include
#include
int ModeDarkness(int basePixel,int mixPixel);//變暗模式
int ModeMultiply(int basePixel,int mixPixel);//正片疊底模式
int ModeColorDark(int basePixel,int mixPixel);//顏色加深模式
int ModeLinearDark(int basePixel,int mixPixel);//線性漸變模式
int* ModeDark(int baseRed,int baseGreen,int baseBlue,int mixRed,int mixGreen,int mixBlue);//深色模式
int ModeLighten(int basePixel,int mixPixel);//變亮模式
int ModeFilterColor(int basePixel,int mixPixel);//濾色模式
int ModeColorLighten(int basePixel,int mixPixel);//顏色減淡模式
int ModeColorLinearLighten(int basePixel,int mixPixel);//顏色線性減淡模式
int* ModeLightColor(int baseRed,int baseGreen,int baseBlue,int mixRed,int mixGreen,int mixBlue);//淺色模式
int ModeSuperposition(int basePixel,int mixPixel);//疊加模式
int ModeSmoothLight(int basePixel,int mixPixel);//柔光模式
int ModeStrongLight(int basePixel,int mixPixel);//強光模式
int ModeHightLight(int basePixel,int mixPixel);//亮光模式
int ModeLinearLight(int basePixel,int mixPixel);//線性光模式
int ModePointLight(int basePixel,int mixPixel);//點光模式
int* ModeSolidColorMixing(int baseRed,int baseGreen,int baseBlue,int mixRed,int mixGreen,int mixBlue);
int ModeDifference(int basePixel,int mixPixel);//差值模式
int ModeExclude(int basePixel,int mixPixel);//排除模式
int ModeSubtract(int basePixel,int mixPixel);//減去模式
int ModeDivide(int basePixel,int mixPixel);//劃分模式
int ModeGray(int red,int green,int blue);//去色
int* ModeColorInverse(int red,int green,int blue);//反相
int CheckRange(int value);
int CheckValue(int value);
int getPSGray(int pixel);
#endif
Specialeffect.c
#include
#include
#include
#include
#include
/*int CheckValue(int value)
{
return (value & ~0xff)==0?value:value>255?255:0;
};*/
int CheckRange(int value)
{
return (value & ~0xff)==0?value:value>255?255:0;
/*int res = 0;
res = value > 255 ? 255 : (value < 0 ? 0 : value);
return res*/;
};
int ModeGray(int red,int green,int blue)
{
int min = 0,max = 0;
min = red < green ? (red < blue ? red : blue) : (green
max = red > green ? (red > blue ? red : blue) : (green>blue?green:blue);
return (min + max)/2;
};
int getPSGray(int pixel)
{
int red = 0,green = 0,blue = 0,min = 0,max = 0;
red = ((pixel >> 16) & 0xFF);
green = ((pixel >> 8) & 0xFF);
blue = (pixel & 0xFF);
min = red < green ? (red < blue ? red : blue) : (green
max = red > green ? (red > blue ? red : blue) : (green>blue?green:blue);
return (min + max)/2;
};
int ModeDarkness(int basePixel,int mixPixel)
{
int res = 0;
res = (basePixel>mixPixel?mixPixel:basePixel);
return res;
};
int ModeMultiply(int basePixel,int mixPixel)
{
int res = 0;
res = mixPixel * basePixel / 255;
return CheckRange(res);
};
int ModeColorDark(int basePixel,int mixPixel)
{
int res = 0;
int temp = basePixel + mixPixel - 255;
temp = temp<0?0:temp;
if(mixPixel==0)
return basePixel;
res = temp * 255 / mixPixel;
return CheckRange(res);
};
int ModeLinearDark(int basePixel,int mixPixel)//結果色 = 基色 + 混合色 - 255
{
int res = 0;
res = basePixel + mixPixel - 255;
return CheckRange(res);
};
int* ModeDark(int baseRed,int baseGreen,int baseBlue,int mixRed,int mixGreen,int mixBlue)//??
{
int baseSum = 0, mixSum = 0;
int* res = (int*)malloc(sizeof(int)*3);
baseSum = baseRed + baseGreen + baseBlue;
mixSum = mixRed + mixGreen + mixBlue;
if(baseSum
{
res[0] = baseRed;
res[1] = baseGreen;
res[2] = baseBlue;
}
else
{
res[0] = mixRed;
res[1] = mixGreen;
res[2] = mixBlue;
}
return res;
};
int ModeLighten(int basePixel,int mixPixel)
{
int res = 0;
res = (basePixel>mixPixel?basePixel:mixPixel);
return res;
};
int ModeFilterColor(int basePixel,int mixPixel)//255 - 混合色的補色 * 基色補色 / 255
{
int res = 0;
res = 255 - (255 - mixPixel) * (255 - basePixel) / 255;
return CheckRange(res);
};
int ModeColorLighten(int basePixel,int mixPixel)//結果色 = 基色 + (混合色 * 基色) / (255 - 混合色)
{
int res = 0;
res = basePixel + (basePixel * mixPixel) / (256 - mixPixel);
return CheckRange(res);
};
int ModeColorLinearLighten(int basePixel,int mixPixel)
{
int res = 0;
res = basePixel + mixPixel;
return CheckRange(res);
};
int* ModeLightColor(int baseRed,int baseGreen,int baseBlue,int mixRed,int mixGreen,int mixBlue)//??
{
int baseSum = 0, mixSum = 0;
int* res = (int*)malloc(sizeof(int)*3);
baseSum = baseRed + baseGreen + baseBlue;
mixSum = mixRed + mixGreen + mixBlue;
if(baseSum>mixSum)
{
res[0] = baseRed;
res[1] = baseGreen;
res[2] = baseBlue;
}
else
{
res[0] = mixRed;
res[1] = mixGreen;
res[2] = mixBlue;
}
return res;
};
int ModeSuperposition(int basePixel,int mixPixel)//基色 < = 128:結果色 = 混合色 * 基色 / 128;基色 > 128:結果色 = 255 - (255 - 混合色)* (255 - 基色) / 128
{
int res = 0;
res = ((basePixel <= 128) ? (mixPixel * basePixel / 128):(255 - (255 - mixPixel) * (255 - basePixel) / 128));
return CheckRange(res);
};
int ModeSmoothLight(int basePixel,int mixPixel)
{
int res = 0;
res = mixPixel > 128 ? ((int)((float)basePixel+((float)mixPixel+(float)mixPixel-255.0f)*((sqrt((float)basePixel/255.0f))*255.0f-(float)basePixel)/255.0f)):
((int)((float)basePixel+((float)mixPixel+(float)mixPixel-255.0f)*((float)basePixel-(float)basePixel*(float)basePixel/255.0f)/255.0f));
return CheckRange(res);
};
int ModeStrongLight(int basePixel,int mixPixel)
{
int res = 0;
res = mixPixel <= 128 ? (mixPixel * basePixel / 128):(255 - (255 - mixPixel) * (255 - basePixel) / 128);
return CheckRange(res);
};
int ModeHightLight(int basePixel,int mixPixel)
{
int res = 0;
if (mixPixel <= 128)
res = mixPixel == 0 ? basePixel : (basePixel - (255 - basePixel)*(255-2*mixPixel) / (2 * mixPixel));
else
res = mixPixel == 255 ? basePixel : basePixel+ (basePixel*(2*mixPixel-255))/(255-(2*mixPixel-255));
return CheckRange(res);
};
int ModeLinearLight(int basePixel,int mixPixel)
{
int res = 0;
res = 2 * mixPixel + basePixel - 255;
return CheckRange(res);
};
int ModePointLight(int basePixel,int mixPixel)
{
int res = 0;
int a = mixPixel + mixPixel - 255;
int b = mixPixel + mixPixel;
if(basePixel < a)
res = b - 255;
if(basePixel >= a && basePixel < b)
res = basePixel;
if(basePixel > b)
res = b;
return CheckRange(res);
};
int* ModeSolidColorMixing(int baseRed,int baseGreen,int baseBlue,int mixRed,int mixGreen,int mixBlue)
{
int* res = (int*)malloc(sizeof(int)*3);
res[0] = baseRed + mixRed;
res[1] = baseGreen + mixGreen;
res[2] = baseBlue + mixBlue;
res[0] = res[0]>255?255:0;
res[1] = res[1]>255?255:0;
res[2] = res[2]>255?255:0;
return res;
};
int ModeDifference(int basePixel,int mixPixel)
{
int res = 0;
res = abs(mixPixel - basePixel);
return res;
};
int ModeExclude(int basePixel,int mixPixel)
{
int res = 0;
res = (mixPixel + basePixel) - mixPixel * basePixel / 128;
return CheckRange(res);
};
int ModeSubtract(int basePixel,int mixPixel)
{
int res = 0;
res = basePixel - mixPixel;
return CheckRange(res);
};
int ModeDivide(int basePixel,int mixPixel)
{
int res = 0;
if(mixPixel == 0)
return basePixel;
res = 255 * basePixel / mixPixel;
return CheckRange(res);
};
int* ModeColorInverse(int red,int green,int blue)
{
int* res = (int*)malloc(sizeof(int)*3);
res[0] = 255 - red;
res[1] = 255 - green;
res[2] = 255 - blue;
return res;
};
demo: http://www.zealfilter.com/forum.php?mod=viewthread&tid=70&extra=page%3D1
(原文:http://blog.csdn.net/bravebean/article/details/51392440)
相關文章
- 常用的畫素操作演算法:影象加法、畫素混合、提取影象中的ROI演算法
- 影象濾鏡--圖象扭曲演算法演算法
- 綜述:影象風格化演算法最全盤點 | 內附大量擴充套件應用演算法套件
- 數字影象處理之二維碼影象提取演算法(一)演算法
- 圖的鄰接表演算法---(附完整程式碼)演算法
- 【資料結構與演算法】模式匹配——從BF演算法到KMP演算法(附完整原始碼)資料結構演算法模式KMP原始碼
- PS圖層混合演算法之二(線性加深,線性減淡,變亮,變暗)演算法
- 【資料結構與演算法】字典樹(附完整原始碼)資料結構演算法原始碼
- 演算法排序:史上最全2演算法排序
- 影象主題色提取演算法演算法
- 影象美容之眼睛放大演算法。演算法
- 神奇的影象處理演算法演算法
- 【資料結構與演算法】Huffman樹&&Huffman編碼(附完整原始碼)資料結構演算法原始碼
- 【資料結構與演算法】內部排序總結(附各種排序演算法原始碼)資料結構演算法排序原始碼
- nms 演算法演示(附程式碼)演算法
- 基於AI排序演算法的指數增強策略【附原始碼】AI排序演算法原始碼
- 監督式機器學習演算法的應用:擇時【附原始碼】機器學習演算法原始碼
- React原始碼分析 - Diff演算法React原始碼演算法
- 【PS演算法理論探討一】 Photoshop中兩個32點陣圖像混合的計算公式(含不透明度和圖層混合模式)。演算法公式模式
- 影象相似度中的Hash演算法演算法
- 影象處理的濾鏡演算法演算法
- 【資料結構與演算法】自己動手實現圖的BFS和DFS(附完整原始碼)資料結構演算法原始碼
- 解密Oracle資料存取演算法(附程式碼、演算法分析)解密Oracle演算法
- PS圖層混合演算法之一(不透明度,正片疊底,顏色加深,顏色減淡)演算法
- Bag of Features (BOF)影象檢索演算法演算法
- №窮舉密碼演算法指要(原始碼) (轉)密碼演算法原始碼
- MATLAB影象旋轉原始碼Matlab原始碼
- Photoshop圖層混合模式計算公式大全(轉)模式公式
- 05EM演算法-高斯混合模型-GMM演算法模型
- PhxPaxos原始碼分析——Paxos演算法實現原始碼演算法
- 經典演算法研究系列:九、影象特徵提取與匹配之SIFT演算法演算法特徵
- 一文讀懂影象壓縮演算法演算法
- 【影象演算法】高斯模糊+徑向縮放模糊演算法
- 【資料結構與演算法】HashTable相關操作實現(附完整原始碼)資料結構演算法原始碼
- 目標檢測演算法盤點(最全)演算法
- 安卓圖片瀏覽(支援超大圖,附原始碼)安卓原始碼
- 【JAVA演算法】圖論演算法 -- Dijkstra演算法Java演算法圖論
- WebRTC 音訊演算法 附完整C程式碼Web音訊演算法C程式