9

The following code is used to create a 8 bit bitmap

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

But when i save it it is saved as a 8 bit color bitmap. Is it possible to directly create a 8 bit grayscale bitmap without creating a 8 bit color bitmap and later having to convert it to a grayscale ?

Ravi Gadag
  • 15,735
  • 5
  • 57
  • 83
klijo
  • 15,761
  • 8
  • 34
  • 49

2 Answers2

13

I just met this problem and solved it, with the help of this.

But I will put my quick solution here, hope it helps you.
BITMAP files contain four parts, one is the palette, which decides how the colors should be displayed. So here we modify the palette of our Bitmap file:

myBMP = new Bitmap(_xSize, _ySize, _xSize, System.Drawing.Imaging.PixelFormat.Format8bppIndexed, _pImage);
//_pImage is the pointer for our image
//Change palatte of 8bit indexed BITMAP. Make r(i)=g(i)=b(i)
ColorPalette _palette = myBMP.Palette;
Color[] _entries = _palette.Entries;
for (int i = 0; i < 256; i++)
{
    Color b = new Color();
    b = Color.FromArgb((byte)i, (byte)i, (byte)i);
    _entries[i] = b;
}
myBMP.Palette = _palette;
return myBMP;
funie200
  • 3,688
  • 5
  • 21
  • 34
richieqianle
  • 602
  • 2
  • 7
  • 20
  • A much safer way than a pointer to write data into an 8 bit image is to have the data in an array [and copy it in using `LockBits` and `Marshal.Copy`](https://stackoverflow.com/a/43967594/395685). – Nyerguds Feb 03 '18 at 13:50
  • Side note... `Color.FromArgb` takes integers as arguments. There is no need for casts there. – Nyerguds May 24 '18 at 05:39
  • _entries[i] = Color.FromArgb(i,i,i) // this would have sufficed in the loop – Daniklad Feb 22 '21 at 08:08
3

If you have a bitmap that has a palette then there's not really a notion of whether the bmp is greyscale or not. As long as all colours in the palette are greyscale then the bmp is.

This code should help (it's VB but should be easy to translate):

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 

Found here: http://social.msdn.microsoft.com/Forums/en-us/vblanguage/thread/500f7827-06cf-4646-a4a1-e075c16bbb38

George Duckett
  • 31,770
  • 9
  • 95
  • 162
  • well from that thread i read that there is no such thing as a 8 bit grayscale bitmap format. Its the color Palette that needs to be grayscale. Is this correct ? – klijo Dec 22 '11 at 13:01