Reputation: 429
I'm trying work with BitmapData class? and have some problems with assigning IntPtr value to the BitmapData.Scan0 property. Here is my code:
var data = bmp.LockBits(new rectangle(Point.Empty, bmp.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
data.Scan0 = rh.data.Scan0HGlobal;
bmp.UnlockBits(data);
But, after unlocking image, it doesn't changes. Why? In debugging mode i saw that data.Scan0 was changed to the rh.data.Scan0HGlobal value. In rh.data.Scan0HGlobal i have pointer to the memory where contains raw data of pixels.
Upvotes: 2
Views: 366
Reputation: 1868
Here's how you should do it:
// Lock image bits.
// Also note that you probably should be using bmp.PixelFormat instead of
// PixelFormat.Format32bppArgb (if you are not sure what the image pixel
// format is).
var bmpData = bmp.LockBits(new Rectangle(Point.Empty, bmp.Size),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
// This is total number of bytes in bmp.
int byteCount = bmpData.Stride * bmp.Height;
// And this is where image data will be stored.
byte[] rgbData = new byte[byteCount];
// Copy bytes from image to temporary byte array rgbData.
System.Runtime.InteropServices.Marshal.Copy(
bmpData.Scan0, rgbData, 0, byteCount);
// TODO: Work with image data (now in rgbData), perform calculations,
// set bytes, etc.
// If this operation is time consuming, perhaps you should unlock bits
// before doing it.
// Do remember that you have to lock them again before copying data
// back to the image.
// Copy bytes from rgbData back to the image.
System.Runtime.InteropServices.Marshal.Copy(
rgbData, 0, bmpData.Scan0, byteCount);
// Unlock image bits.
image.UnlockBits(bmpData);
// Save modified image, or do whatever you want with it.
Hope it helps!
Upvotes: 1
Reputation: 942257
Well, it's a bit sad that Scan0 property setter is not private. But yes, this doesn't do anything. You'll need to copy the bytes yourself to alter the image. Use Marshal.Copy() to copy through a byte[] helper array of pinvoke memcpy().
Upvotes: 4