Search code examples
c#system.drawing

Create 8 bit bitmap from array


I am trying to create a bitmap from an array of pixels.

var height = 2;
var width = 2;
var output = new byte[4] { 0, 0, 0, 0 };
var gcHandle = GCHandle.Alloc(output, GCHandleType.Pinned);

var stride = width * sizeof(byte);
var pointer = gcHandle.AddrOfPinnedObject();
using (var bitmap = new Bitmap(width, height, stride, PixelFormat.Format8bppIndexed, pointer))
{
}

However I get System.ArgumentException: 'Parameter is not valid.', with no inner exception or further details.

I don't want to use SetPixel because my real array is very large.

This is using the System.Drawing.Common 4.5.0 library for .Net Standard 2.0


Solution

  • You could do something like this maybe:

    unsafe public static void Main()
    {
       var height = 2;
       var width = 2;
       var output = new byte[4] { 1, 2, 3, 4};
       using (var bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed))
       {
          var data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
          Marshal.Copy(data.Scan0, output, 0, 4);
          bitmap.UnlockBits(data);
          bitmap.Save(@"D:\blah.bmp");
       }
    }
    

    Bitmap.LockBits Method

    Bitmap.LockBits Method

    Locks a Bitmap into system memory.

    Marshal.Copy Method

    Copies data from a managed array to an unmanaged memory pointer, or from an unmanaged memory pointer to a managed array.


    As noted just work in the 32bpp, and make your life easier

    public static void Main()
    {
       var height = 2;
       var width = 2;
       var c = Color.White.ToArgb();
       var output = new int[4] { c, c, c, c };
       using (var bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed))
       {
          var data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);
    
          Marshal.Copy(output, 0, data.Scan0, 4);
          bitmap.UnlockBits(data);
          bitmap.Save(@"D:\trdy.bmp");
       }
    }