2011-12-18 156 views
4

這是我的位圖對象轉換8位色的BMP圖像到8位灰度BMP

Bitmap b = new Bitmap(columns, rows, PixelFormat.Format8bppIndexed); 
BitmapData bmd = b.LockBits(new Rectangle(0, 0, columns, rows), ImageLockMode.ReadWrite, b.PixelFormat); 

如何轉換成8位灰度位圖呢?

+0

爲什麼你使用'LockBits'? – Oded 2011-12-18 20:10:50

+1

http://www.bobpowell.net/grayscale.htm – Oded 2011-12-18 20:12:59

+0

不要忘記標記答案被接受,在你檢查後看看是否適合你。雖然所有的答案都基本相同 – 2011-12-28 08:59:40

回答

2

嗨,你可以儘管下面的代碼是Vb.net調色板更改爲灰度一個

。你可以很容易地將其轉換爲C#

Private Function GetGrayScalePalette() As ColorPalette 
    Dim bmp As Bitmap = New Bitmap(1, 1, Imaging.PixelFormat.Format8bppIndexed) 

    Dim monoPalette As ColorPalette = bmp.Palette 

    Dim entries() As Color = monoPalette.Entries 

    Dim i As Integer 
    For i = 0 To 256 - 1 Step i + 1 
     entries(i) = Color.FromArgb(i, i, i) 
    Next 

    Return monoPalette 
End Function 

原文出處 - >http://social.msdn.microsoft.com/Forums/en-us/vblanguage/thread/500f7827-06cf-4646-a4a1-e075c16bbb38

+0

除非原始圖像的調色板已經按照某種完整的奇蹟按亮度排序,否則只需將該調色板分配給圖像即可完全解決問題。 – Nyerguds 2018-01-09 08:15:56

3

喜歡的東西:

Bitmap b = new Bitmap(columns, rows, PixelFormat.Format8bppIndexed); 
for (int i = 0; i < columns; i++) 
{ 
    for (int x = 0; x < rows; x++) 
    { 
     Color oc = b.GetPixel(i, x); 
     int grayScale = (int)((oc.R * 0.3) + (oc.G * 0.59) + (oc.B * 0.11)); 
     Color nc = Color.FromArgb(oc.A, grayScale, grayScale, grayScale); 
     b.SetPixel(i, x, nc); 
    } 
} 
BitmapData bmd = b.LockBits(new Rectangle(0, 0, columns, rows), ImageLockMode.ReadWrite, b.PixelFormat); 
+2

這是否夠用?你不需要更改顏色表嗎?因爲仍然修改的位圖數據仍將使用相同的顏色表? – klijo 2011-12-22 11:01:22

+0

「SetPixel」是否適用於索引圖像?它們的索引是像素值,而不是顏色。 – Nyerguds 2018-01-09 08:17:47

5

是的,沒有必要改變的像素,只是調色板是罰款。 ColorPalette是片狀型,此示例代碼運行良好:

 var bmp = Image.FromFile("c:/temp/8bpp.bmp"); 
     if (bmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format8bppIndexed) throw new InvalidOperationException(); 
     var newPalette = bmp.Palette; 
     for (int index = 0; index < bmp.Palette.Entries.Length; ++index) { 
      var entry = bmp.Palette.Entries[index]; 
      var gray = (int)(0.30 * entry.R + 0.59 * entry.G + 0.11 * entry.B); 
      newPalette.Entries[index] = Color.FromArgb(gray, gray, gray); 
     } 
     bmp.Palette = newPalette; // Yes, assignment to self is intended 
     if (pictureBox1.Image != null) pictureBox1.Image.Dispose(); 
     pictureBox1.Image = bmp; 

其實我不建議您使用此代碼,索引的像素格式是對付一個皮塔。您可以在this answer中找到快速且更一般的彩色灰度轉換。

+0

8位調色板條目是否始終相同?我以爲你可以使用優化的優化圖像。如果它只有我可以使用var gray =(int)(0.30 * entry.R + 0.59 * entry.G + 0.11 * entry.B);對 ? – crowso 2011-12-22 14:48:17

+1

只有當您需要將24bpp圖像轉換爲8bpp圖像時,纔會優化調色板。這需要將1600萬種可能的顏色映射到僅256種可用顏色。這不是你要求的。 – 2011-12-22 14:52:19

+0

,這意味着C#在創建8位圖像時總是將默認調色板放入? – crowso 2011-12-22 14:55:03

0

檢查此link了。我們在大學做到了這一點,它工作。

這就是您所需要的全部輸入和輸出。

2

請注意,如果您想要進行與現代HDTV相同的轉換,您需要使用Rec。轉換的709個係數。上面提供的(.3,.59,.11)(幾乎)是Rec。 601(標準def)係數。建議709個係數是灰度= 0.2126 R'+ 0.7152 G'+ 0.0722 B',其中R',G'和B'是伽馬調整的紅色,綠色和藍色分量。