2014-02-24 119 views
10

我有一個灰度圖像。我想篩選它以使white -> color1black -> color2。這兩種顏色都採用十六進制CSS語法。我需要做什麼數學來獲得這種效果?feColorMatrix過濾器中的顏色匹配

我使用這個語法:

<!-- just an example --> 
<filter id="colorMeMatrix"> 
    <feColorMatrix in="SourceGraphic" 
    type="matrix" 
    values="0 0 0 0 0 
      1 1 1 1 0 
      0 0 0 0 0 
      0 0 0 1 0" /> 

+0

我沒有時間寫它現在,但這可能讓你開始:http://codepen.io/AmeliaBR/pen/AiHEJ – AmeliaBR

回答

40

要了解你的需要,你必須清楚地定義你開始用什麼,你想落得什麼樣的矩陣, colour matrix filter如何工作。

矩陣有五列四行。每行代表輸出數字之一:R,G,B,A。這些列表示您的輸入RGBA和常量1.您可以通過將行中的每個值乘以相應的輸入值來計算每行的輸出值。

輸入和輸出數字標準化,範圍在0-1之間,所以你不必通過256

所以對於您的示例矩陣擔心相乘的一切:

 /*R G B A 1 */ 
     0 0 0 0 0 // R = 0*R + 0*G + 0*B + 0*A + 0 
     1 1 1 1 0 // G = 1*R + 1*G + 1*B + 1*A + 0 
     0 0 0 0 0 // B = 0*R + 0*G + 0*B + 0*A + 0 
     0 0 0 1 0 // A = 0*R + 0*G + 0*B + 1*A + 0 

它採用輸入顏色,將所有四個通道(RGBA)相加,並將結果作爲綠色通道。紅色和藍色通道爲零,alpha通道不變。因此,您的照片會以黑色區域仍然黑色結束,但所有彩色/灰色/白色/透明區域都會轉換爲綠色陰影。

這不是你想要的,當然。您希望黑色區域具有一種顏色,白色區域具有另一種顏色,並且所有灰色區域都位於兩者之間。

要使黑色區域具有某種顏色,必須設置矩陣的常數因子參數。輸入的RGB值對於黑色將爲零,因此它們在此處不考慮。

如果你的顏色2,要在黑白圖像使用黑色的價值,是(R2,G2,B2),那麼這就是你的常數因子必須是:

 /*R G B A 1 */ 
     ? ? ? 0 r2 // R = ?*0 + ?*0 + ?*0 + 0*0 + r2 = r2 
     ? ? ? 0 g2 // G = ?*0 + ?*0 + ?*0 + 0*0 + g2 = g2 
     ? ? ? 0 b2 // B = ?*0 + ?*0 + ?*0 + 0*0 + b2 = b2 
     0 0 0 1 0 // A = 1*A 

當然,上面的矩陣會將任意輸入顏色轉換爲該輸出顏色,因爲它不會影響輸入RGBA值中的任何內容。爲了得到你想要的漸變,你需要白色區域 - 那些輸入值爲1的R,G和B的顏色最終以colour1結尾,我將把它寫成(r1,g1,b1)。

現在,爲了使事情變得更容易,請記住,對於灰度圖像,任何點的R,G和B值都是相等的。所以我們可以使用這些值中的任何一個作爲輸入並忽略其他值。因此,如果我們只是將R因子爲每個通道,當輸入值是白色輸入R等於1,方程是

 /*R G B A 1 */ 
     ? 0 0 0 r2 // R = ?*1 + r2 = r1 
     ? 0 0 0 g2 // G = ?*1 + g2 = g1 
     ? 0 0 0 b2 // B = ?*1 + b2 = b1 
     0 0 0 1 0 // A = 1*A 

簡單代數告訴你,爲了使這些方程的工作,你需要與colour1和顏色2值之間的差代替問號:

 /* R G B A 1 */ 
     (r1-r2) 0 0 0 r2 // R = (r1-r2)*1 + r2 = r1 
     (g1-g2) 0 0 0 g2 // G = (g1-g2)*1 + g2 = g1 
     (b1-b2) 0 0 0 b2 // B = (b1-b2)*1 + b2 = b1 
      0 0 0 1 0 // A = 1*A 

例如,如果要輸入的圖像的白色區域映射到青色(R = 0,G = 1,b = 1 )和黑色輸入區域映射到深紫色(r = 0.1,g = 0,b = 0)。2),你可以使用一個矩陣像

 /*R G B A 1 */ 
     -0.1 0 0 0 0.1 // R = (-0.1)*R + 0.1 
      1 0 0 0 0 // G = 1*R + 0 
     0.8 0 0 0 0.2 // B = 0.8*R + 0.2 
      0 0 0 1 0 // A = 1*A 

Using that matrix in a filter應用於this original image

請注意,這實際上與我在評論中鏈接到的示例完全不同;在那個過濾器中,我試圖保持白色和黑色一樣黑,但將灰色改爲彩色。爲此我使用了伽瑪校正濾鏡,而不是顏色矩陣。

+1

非常好的解釋! – vals

+3

你可能想要爲你的濾鏡添加一個color-interpolation-filters =「sRGB」屬性 - 它爲圖像提供了更自然的顏色插值(它是伽馬校正的) –

+0

@MichaelMullany我還沒有玩過 - 它確實有很大的不同,儘管我不知道sRGB版本更好。你只需要知道你想要什麼,並確保你在正確的顏色空間中計算你的顏色的RGB值。我更新了[鏈接示例](http://codepen.io/AmeliaBR/pen/mtKiH)進行比較。 – AmeliaBR