2016-09-25 111 views
0

我正在嘗試創建一個採用灰度圖像和顏色的函數,並使用該顏色的陰影使灰度圖像着色但保持灰度圖像的着色級別。該功能也不應該爲圖像的透明部分着色。我有多個圖層(多個PNG的),我會稍後合併,只需要對某些圖層進行着色。我環顧四周,發現了類似的東西,但並不完全符合我的需求。我知道如何在HTML5前端爲使用Canvas的用戶做到這一點,但我需要一種方法在後端實現同樣的事情,我猜測是使用解鎖位圖內存調用或ColorMatrix類的手動方法。任何人都可以幫助我,圖形並不是我最強的領域,但我正在慢慢學習。查看下面的函數,瞭解我在C#中需要的內容。否則隱藏畫布的東西並不重要,因爲我在做這個服務器端保存到PNG文件...在c中將灰度部分透明的圖像轉換爲單一顏色#

function drawImage(imageObj, color) { 
    var hidden_canvas = document.createElement("canvas"); 
    hidden_canvas.width = imageObj.width; 
    hidden_canvas.height = imageObj.height; 
    var hidden_context = hidden_canvas.getContext("2d"); 

    // draw the image on the hidden canvas 
    hidden_context.drawImage(imageObj, 0, 0); 

    if (color !== undefined) { 
     var imageData = hidden_context.getImageData(0, 0, imageObj.width, imageObj.height); 
     var data = imageData.data; 

     for (var i = 0; i < data.length; i += 4) { 
      var brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2]; 

      //red 
      data[i] = brightness + color.R; 
      //green 
      data[i + 1] = brightness + color.G; 
      //blue 
      data[i + 2] = brightness + color.B; 
     } 

     //overwrite original image 
     hidden_context.putImageData(imageData, 0, 0); 
    } 

    var canvas = document.getElementById('card'); 
    var context = canvas.getContext('2d'); 
    context.drawImage(hidden_canvas, 0, 0); 
}; 
+0

我會強烈建議使用ImageMagick .NET這樣的事情。 https://magick.codeplex.com。它是免費的,完美適用於這類東西。爲什麼重新發明輪子? –

+0

@PeterMoore不,不認爲ImageMagick是解決方案。這傢伙要求一個非常具體的圖像處理場景。 –

+0

使用'Bitmap'類將圖像加載到內存。你可以遍歷所有像素GetPixel,並通過SetPixel處理每個像素。總之,你只需要學習如何正確使用該類來將你的算法從JavaScript轉換爲C#。 –

回答

1

這應該做的工作:

public static Bitmap MakeChromaChange(Bitmap bmp0, Color tCol, float gamma) 
{ 
    Bitmap bmp1 = new Bitmap(bmp0.Width, bmp0.Height); 

    using (Graphics g = Graphics.FromImage(bmp1)) 
    { 
     float f = (tCol.R + tCol.G + tCol.B)/765f; 
     float tr = tCol.R/255f - f; 
     float tg = tCol.G/255f - f; 
     float tb = tCol.B/255f - f; 

     ColorMatrix colorMatrix = new ColorMatrix(new float[][] 
     { new float[] {1f + tr, 0, 0, 0, 0}, 
      new float[] {0, 1f + tg, 0, 0, 0}, 
      new float[] {0, 0, 1f + tb, 0, 0}, 
      new float[] {0, 0, 0, 1, 0}, 
      new float[] {0, 0, 0, 0, 1} }); 

     ImageAttributes attributes = new ImageAttributes(); 
     attributes.SetGamma(gamma); 
     attributes.SetColorMatrix(colorMatrix); 

     g.DrawImage(bmp0, new Rectangle(0, 0, bmp0.Width, bmp0.Height), 
      0, 0, bmp0.Width, bmp0.Height, GraphicsUnit.Pixel, attributes); 
    } 
    return bmp1; 
} 

注意,我養了伽瑪參數;如果你不需要它,保留值在1f;

這是在工作中,將第一個紅色則更多的紅色和藍色部分:

enter image description hereenter image description hereenter image description here

透明像素不受影響。

欲瞭解更多關於ColorMatrix這裏是一個really nice intro

作爲一個有趣的項目,我申請已知的顏色,以一個已知的臉:

enter image description here

+0

我會在一兩天後對它進行測試,然後回覆你。謝謝 – kyleb

+0

這大部分都是正確的,但必須稍微調整一下數字以適應他們的需要。 – kyleb

+0

是的,這是完全可能的,這取決於您的要求:慎重扭曲或全面設置色調..您可能想要解釋您需要更改的內容;也許我們可以改進答案.. – TaW