2013-05-02 268 views
5

對於Bitmap,有一個MakeTransparent方法,是否有一個類似的用於將一種顏色更改爲另一種顏色?您可以在位圖圖像中將一種顏色更改爲另一種顏色嗎?

// This sets Color.White to transparent 
Bitmap myBitmap = new Bitmap(sr.Stream); 
myBitmap.MakeTransparent(System.Drawing.Color.White); 

有什麼可以做這樣的事嗎?

Bitmap myBitmap = new Bitmap(sr.Stream); 
myBitmap.ChangeColor(System.Drawing.Color.Black, System.Drawing.Color.Gray); 

回答

-1

您可以使用SetPixel爲:

private void ChangeColor(Bitmap s, System.Drawing.Color source, System.Drawing.Color target) 
{ 
    for (int x = 0; x < s.Width; x++) 
    { 
     for (int y = 0; y < s.Height; y++) 
     { 
      if (s.GetPixel(x, y) == source) 
       s.SetPixel(x, y, target); 
     }     
    } 
} 

GetPixel和SetPixel周圍的gdiplus.dll功能GdipBitmapGetPixel和GdipBitmapSetPixel包裝相應

Remarks

根據位圖格式,GdipBitmapGetPixel可能不是 返回的值與GdipBitmapSetPixel設置的值相同。例如,如果您在其像素格式爲 爲32bppPARGB的位圖對象上調用GdipBitmapSetPixel,則該像素的RGB分量是預乘的,例如 。由於四捨五入,後續調用GdipBitmapGetPixel可能會返回不同的值 。此外,如果您在位圖顏色深度爲每像素16位的對象 上調用GdipBitmapSetPixel,則在從32位轉換爲16位期間信息可能會丟失 ,並且隨後調用 至GdipBitmapGetPixel可能會返回不同的值。

+1

低效的調用,並完全以短的答案。 – SimpleVar 2013-05-02 19:34:58

+1

所以,如果我有一張圖片,我必須得到'GetPixel'和'SetPixel' _n_次,其中_n_是像素的數量。因此,對於一個普通的圖像,甚至是一個標誌,這可能是_n_ = 150k + ... – 2013-05-02 19:37:26

+1

如果在這種語言中已經存在一種方法,它不會在背景中做同樣的迭代嗎? ... – ChocapicSz 2015-09-24 12:20:50

-1

您需要一個庫,它提供了一種方法來修改圖像的顏色空間,而無需使用像素。 LeadTools有一個非常廣泛的圖像庫,您可以使用它支持色彩空間修改,including swapping colors

8

通過對Yorye Nathan的評論的好奇心,這是我通過修改http://msdn.microsoft.com/en-GB/library/ms229672(v=vs.90).aspx創建的擴展。

它可以將位圖中的所有像素從一種顏色變成另一種顏色。

public static class BitmapExt 
{ 
    public static void ChangeColour(this Bitmap bmp, byte inColourR, byte inColourG, byte inColourB, byte outColourR, byte outColourG, byte outColourB) 
    { 
     // Specify a pixel format. 
     PixelFormat pxf = PixelFormat.Format24bppRgb; 

     // Lock the bitmap's bits. 
     Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 
     BitmapData bmpData = 
     bmp.LockBits(rect, ImageLockMode.ReadWrite, 
        pxf); 

     // Get the address of the first line. 
     IntPtr ptr = bmpData.Scan0; 

     // Declare an array to hold the bytes of the bitmap. 
     // int numBytes = bmp.Width * bmp.Height * 3; 
     int numBytes = bmpData.Stride * bmp.Height; 
     byte[] rgbValues = new byte[numBytes]; 

     // Copy the RGB values into the array. 
     Marshal.Copy(ptr, rgbValues, 0, numBytes); 

     // Manipulate the bitmap 
     for (int counter = 0; counter < rgbValues.Length; counter += 3) 
     { 
      if (rgbValues[counter] == inColourR && 
       rgbValues[counter + 1] == inColourG && 
       rgbValues[counter + 2] == inColourB) 

      { 
       rgbValues[counter] = outColourR; 
       rgbValues[counter + 1] = outColourG; 
       rgbValues[counter + 2] = outColourB; 
      } 
     } 

     // Copy the RGB values back to the bitmap 
     Marshal.Copy(rgbValues, 0, ptr, numBytes); 

     // Unlock the bits. 
     bmp.UnlockBits(bmpData); 
    } 
} 

通過bmp.ChangeColour(0,128,0,0,0,0);

+4

謝謝。幫助過我。您還可以修改代碼以使用透明PNG。只需將像素格式更改爲「PixelFormat.Format32bppArgb」,然後將「計數器」增加4而不是3.我需要這樣做,否則代碼會弄亂透明背景。 – 2015-04-02 07:51:11

+0

@RobertS。 - 謝謝,很高興知道:)很高興幫助太 – Sayse 2015-04-02 07:55:47

+1

謝謝。非常有用。 但紅色和藍色的位是倒置的。 ;-) – 2015-09-16 16:04:06

相關問題