C# Getting the pixel data efficiently from System.Drawing.Bitmap
I think this is your best bet.
var bitmapData = scaledBitmap.LockBits(...);
var length = bitmapData.Stride * bitmapData.Height;
byte[] bytes = new byte[length];
// Copy bitmap to byte[]
Marshal.Copy(bitmapData.Scan0, bytes, 0, length);
scaledBitmap.UnlockBits(bitmapData);
You have to copy it, if you want a pass around a byte[].
You don't have to delete the bytes that were allocated, you just need to Dispose of the original Bitmap object when done as it implements IDisposable.
Arokh
Updated on June 15, 2020Comments
-
Arokh almost 4 years
I have several (~2GB) raw 24bpp RGB files on HDD. Now I want to retrieve a portion of it and scale it to the desired size.
(The only scales allowed are 1, 1/2, 1/4, 1/8, ..., 1/256)So I'm currently reading every line from the rectangle of interest into an array, which leaves me with a bitmap which has correct height but wrong width.
As the next step I'm creating a Bitmap from the newly created array.
This is done with by using a pointer so there is no copying of data involved.
Next I'm calling GetThumbnailImage on the Bitmap, which creates a new bitmap with the correct dimensions.Now I want to return the raw pixel data (as a byte array) of the newly created bitmap. But to achieve that I'm currently copying the data using LockBits into a new array.
So my question is: Is there a way to get the pixel data from a Bitmap into a byte array without copying it?
Something like:
var bitmapData = scaledBitmap.LockBits(...) byte[] rawBitmapData = (byte[])bitmapData.Scan0.ToPointer() scaledBitmap.UnlockBits(bitmapData) return rawBitmapData
I'm well aware that this doesn't work, it is just an example to what I basically want to achieve.
-
Arokh over 12 yearsNot exactly the answer I was hoping for, but using Marshal.Copy makes it look a lot nicer than copying it integer per integer. Thanks