Alex Sabaka
Alex Sabaka

Reputation: 429

How to assign one IntPtr to other IntPtr

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

Answers (2)

Nikola Malešević
Nikola Malešević

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

Hans Passant
Hans Passant

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

Related Questions