1

I need to create a bitmap with a filestream. So far I have this Code:

 using (FileStream bmp = File.Create(@"C:\test.bmp"))
        {
            BinaryWriter writer = new BinaryWriter(bmp);
            int i = 0;

          //  writer.Write((char*)&fileheader, sizeof(fileheader));
          //  writer.Write((char*)&infoheader, sizeof(infoheader));

            for (int rows = 0; rows < 160; rows++)
            {
                for (int cols = 0; cols < 112; cols++)
                {
                    writer.Write(CamData[i]);
                    i++;
                }
            }

            bmp.Close();
        }

but I still need the header Informations for the bitmap. My Problem is, that I dont know how to implement they in C#. I know the resolution (320 x 240 ) and my pixeldata are 16 bit grayscale values given in a ushort array.

thanks

h0ppel
  • 347
  • 2
  • 5
  • 21

3 Answers3

0

Seems the System.Drawing classes don't like handling 16 bit grayscale, probably because the underlying GDI+ object sees its colour components as values from 0 to 255, whereas 16 bit grayscale actually means you can have 65535 shades of gray.

This means you have two options: either you switch to PresentationCore, and create your image with that, or you downsample the values to byte size and make an 8-bit grayscale image.

The first option is explained in this answer.

The second option includes three steps:

  • Downsample the data to 1 byte per pixel
  • Generate a grayscale colour palette (since 8-bit grayscale is technically paletted)
  • Create an 8-bit indexed image out of your downsampled data and the palette.

The code:

Byte[] camDataBytes = new Byte[CamData.Length];
for(Int32 i = 0; i < camData.Length; i++)
    camDataBytes[i] = (Byte)(CamData[i] / 256);

Color[] palette = new Color[256];
for(Int32 i = 0; i < 256; i++)
    palette[i] = Color.FromArgb(i,i,i);

using(Bitmap b = BuildImage(camDataBytes, 320, 240, 320, PixelFormat.Format8bppIndexed, palette, null))
    b.Save(@"C:\test.bmp", ImageFormat.Bmp); 

The BuildImage function to create an image out of a byte array can be found here. Assuming the image data is compact 320x240, the stride of the final byte array should be exactly the width, and thus 320.

Nyerguds
  • 5,360
  • 1
  • 31
  • 63
0

There is a constructor to create a Bitmap from a byte array. Then, save it to stream in bmp format, using Bitmap's member functions. See here and here.

  • I cant use the Bitmap class, because I dont have a byte array! I have USHORT values – h0ppel Mar 27 '11 at 13:52
  • 1
    when I use PixelFormat.Format16bppGrayScale I always get an gdi+ error. The other pixelformats works well. After using PixelFormat.Format24bppRgb I get this result: the picture 3 times in the first line![test.bmp][1] [1]: http://i.imgur.com/Cls1e.png – h0ppel Mar 27 '11 at 15:39
-1

Try this:

/// From stream to bitmap...
FileStream fs = new FileStream("test.bmp", FileMode.Open);
Bitmap bmp = new Bitmap(fs);
Mitja Bonca
  • 4,268
  • 5
  • 24
  • 30
  • but I dont want open a existing bitmap. I want to create a new bitmap with a filestream – h0ppel Mar 27 '11 at 14:24
  • @Klaus change the FileMode to FileMode.Create (or any other suitable choice). Anyway I was wondering if fs.Close(); can be immediately issued after the two lines above, or whether the stream should be kept open as long as the bitmap is being used. – ADTC Mar 06 '12 at 15:40