Reputation: 5884
I have an array like byte[] pixels
. Is there any way to create a bitmap
object from that pixels
without copying data? I have a small graphics library, when I need to display image on WinForms
window I just copy that data to a bitmap
object, then I use draw method. Can I avoid this copying process? I remember I saw it somewhere, but maybe my memory is just bad.
Edit: I tried this code and it works, but is this safe?
byte[] pixels = new byte[10 * 10 * 4];
pixels[4] = 255; // set 1 pixel
pixels[5] = 255;
pixels[6] = 255;
pixels[7] = 255;
// do some tricks
GCHandle pinnedArray = GCHandle.Alloc(pixels, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();
// create a new bitmap.
Bitmap bmp = new Bitmap (10, 10, 4*10, PixelFormat.Format32bppRgb, pointer);
Graphics grp = this.CreateGraphics ();
grp.DrawImage (bmp, 0, 0);
pixels[4+12] = 255; // add a pixel
pixels[5+12] = 255;
pixels[6+12] = 255;
pixels[7+12] = 255;
grp.DrawImage (bmp, 0, 40);
Upvotes: 3
Views: 7924
Reputation: 28060
There is a constructor that takes a pointer to raw image data:
Bitmap Constructor (Int32, Int32, Int32, PixelFormat, IntPtr)
Example:
byte[] _data = new byte[]
{
255, 0, 0, 255, // Blue
0, 255, 0, 255, // Green
0, 0, 255, 255, // Red
0, 0, 0, 255, // Black
};
var arrayHandle = System.Runtime.InteropServices.GCHandle.Alloc(_data,
System.Runtime.InteropServices.GCHandleType.Pinned);
var bmp = new Bitmap(2, 2, // 2x2 pixels
8, // RGB32 => 8 bytes stride
System.Drawing.Imaging.PixelFormat.Format32bppArgb,
arrayHandle.AddrOfPinnedObject()
);
this.BackgroundImageLayout = ImageLayout.Stretch;
this.BackgroundImage = bmp;
Upvotes: 6
Reputation: 4159
Couldn't you just use:
System.Drawing.Bitmap.FromStream(new MemoryStream(bytes));
I don't think these method calls will do any copying, as nothing in the MSDN indicate such: http://msdn.microsoft.com/en-us/library/9a84386f
Upvotes: 0