這實際上可以在託管代碼中使用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
,或者通過將字節實際轉換爲顏色對象並進行其他類似的近似(如色調/飽和度/亮度)。
這是你不得不面對的內部優化。如果你想讓背景變成白色,那麼就把它畫在白色的背景上。如果你想恢復原始背景顏色,那麼你必須記住它是什麼。 – 2014-08-27 19:23:43
我可以編寫一個函數與背景拼合圖像,但它似乎應該有一個簡單的解決方案。 – MadTigger 2014-08-27 20:59:58
然後,請不要使用該功能。手動做。 – Nyerguds 2018-01-03 12:16:08