2014-08-27 112 views
1

我使用C#的位圖對象上MakeTransparent()函數調用將圖像轉換爲透明圖像。當這個方法被調用時,它會通過設置alpha通道將背景顏色轉換爲透明,然後將背景顏色轉換爲黑色。我設置得比黑色()與makeTransparent創建圖像以外的顏色如何

我需要找到將這個背景色回白色或快速的方式無論原來的顏色了,因爲有時我需要將圖像拼合到非alpha通道啓用格式。

製作透明似乎並不具有允許你告訴它獨自離開的背景顏色任何標誌或過載,並通過改變像素的圖像像素是方式效率低下。任何人有任何建議或GDI技巧來解決這個問題?

+2

這是你不得不面對的內部優化。如果你想讓背景變成白色,那麼就把它畫在白色的背景上。如果你想恢復原始背景顏色,那麼你必須記住它是什麼。 – 2014-08-27 19:23:43

+0

我可以編寫一個函數與背景拼合圖像,但它似乎應該有一個簡單的解決方案。 – MadTigger 2014-08-27 20:59:58

+0

然後,請不要使用該功能。手動做。 – Nyerguds 2018-01-03 12:16:08

回答

0

似乎有不是一個快速的方法來做到這一點使用託管代碼接口。使用單獨的像素操作,或使用非託管代碼更新像素似乎是唯一真正的選擇。

0

這實際上可以在託管代碼中使用Marshal.Copy將備份字節數組複製出位圖對象,然後對其進行編輯,然後將其複製回來。

因此,基本上,在記住,一般的方法,你只是去以上的像素,逐行,檢測哪個像素有你想要更換的顏色,他們的阿爾法字節設置爲0

注意「 ARGB「是指一個讀像素的值在Int32值內的順序。由於這個值是小端的,所以給定偏移處的字節的實際順序是相反的; B =偏移+ 0,G = OFFSET + 1,R = OFFSET + 2,A =偏移+ 3.

/// <summary> 
/// Clears the alpha value of all pixels matching the given colour. 
/// </summary> 
public static Bitmap MakeTransparentKeepColour(Bitmap image, Color clearColour) 
{ 
    Int32 width = image.Width; 
    Int32 height = image.Height; 
    // Paint on 32bppargb, so we're sure of the byte data format 
    Bitmap bm32 = new Bitmap(width, height, PixelFormat.Format32bppArgb); 
    using (Graphics gr = Graphics.FromImage(bm32)) 
     gr.DrawImage(image, new Rectangle(0, 0, width, height)); 

    BitmapData sourceData = bm32.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bm32.PixelFormat); 
    Int32 stride = sourceData.Stride; 
    // Copy the image data into a local array so we can use managed functions to manipulate it. 
    Byte[] data = new Byte[stride * height]; 
    Marshal.Copy(sourceData.Scan0, data, 0, data.Length); 
    Byte colR = clearColour.R; 
    Byte colG = clearColour.G; 
    Byte colB = clearColour.B; 
    for (Int32 y = 0; y < height; y++) 
    { 
     Int32 inputOffs = y * stride; 
     for (Int32 x = 0; x < width; x++) 
     { 
      if (data[inputOffs + 2] == colR && data[inputOffs + 1] == colG && data[inputOffs] == colB) 
       data[inputOffs + 3] = 0; 
      inputOffs += 4; 
     } 
    } 
    // Copy the edited image data back. 
    Marshal.Copy(data, 0, sourceData.Scan0, data.Length); 
    bm32.UnlockBits(sourceData); 
    return bm32; 
} 

這可以方便地與一個容差水平,而不是一個確切的匹配得到加強,像Math.Abs(data[inputOffs + 2] - colR) < tolerance ,或者通過將字節實際轉換爲顏色對象並進行其他類似的近似(如色調/飽和度/亮度)。

相關問題