Home > .Net > Bitmap construction from raw buffer in C#.NET

Bitmap construction from raw buffer in C#.NET

Recently, I needed to get an image’s buffer from the network, and to store it in a file system.
If needed to work with image files, one can use a C#.NET “Bitmap” class, existing within “System.Drawing” namespace.

This class encapsulates a GDI+ bitmap and supports the next formats: BMP, PNG, JPG, GIF, TIFF and EXIF.
And it has a good API. It is very friendly class. After the object exists, saving appropriate file is a straight forward action:


Bitmap bitmap = ...
bitmap.Save("TargetImageFileName.bmp"); //format selection is possible

But, how the “Bitmap” object should be created from given buffer in memory?
Quick search in MSDN supplied the next solution:


Byte[] buffer = Proxy.GetImageBuffer();
ImageConverter converter = new ImageConverter();
Image image = (Image) converter.ConvertFrom(buffer);
Bitmap bitmap = new Bitmap(image);

// Work with the bitmap ...

This could be a great solution, but not in given case.
The ”ConvertFrom” function of  ”ImageConverter” is looking for image’s header. The buffer contains a pure raw data, and hence is decoded in a wrong way. As a result of memory corruption, ”ArgumentException” is thrown.

So, what is good solution?

In order to initialize “Bitmap” object from a raw data buffer, first we must supply image’s metadata. We must “teach” the Bitmap object about image, it is going to contain.


public Bitmap CreateBitmapFromRawDataBuffer(byte[] buffer)
{
        // Prepare required image's metadata.
        Size imageSize = new Size(300, 200); // Known size.
        PixelFormat imagePixelFormat = PixelFormat.Format16bppGrayScale; // Known type.

        // Set bitmap known image's metadata.
        Bitmap bitmap = new Bitmap(imageSize.Width, imageSize.Height, imagePixelFormat);

        // Prepare working rectangle.
        Rectangle wholeBitmap = new Rectangle(0, 0, bitmap.Width, bitmap.Height);

        // Lock all bitmap's pixels.
        BitmapData bitmapData = bitmap.LockBits(wholeBitmap, ImageLockMode.WriteOnly, imagePixelFormat);

        // Copy the buffer into bitmapData.
        Marshal.Copy(buffer, 0, bitmapData.Scan0, buffer.Length);

        // Unlock  all bitmap's pixels.
        bitmap.UnlockBits(bitmapData);

        return bitmap;
}

That’s all. It works. Use carefully.

Categories: .Net Tags: ,
  1. No comments yet.
  1. No trackbacks yet.