Marshal.Copy/UnlockBits hangs

Go To StackoverFlow.com

3

A user selects a portion of an image for a cut and paste operation. I create a new bitmap, paste the selected portion in the new image, wipe the source array and paste it back into the old image. Works but at least half the time it hangs with Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Any thoughts or help?

public BitmapSource CutToNew(double left, double top, double width, double height, double pageWidth, double pageHeight)
{
    var destBmp = new Bitmap((int)pageWidth, (int)pageHeight);
    var g = Graphics.FromImage(destBmp);
    g.FillRectangle(new SolidBrush(Color.White), 0, 0, 
       (int)pageHeight, (int)pageWidth);
    g.Dispose();

    var croppedArea = new Rectangle((int)left, (int)top, (int)width, (int)height);
    BitmapData croppedSource = _bitmapImage.LockBits(croppedArea, 
          ImageLockMode.ReadWrite, BitmapImage.PixelFormat);
    var croppedDestArea = new Rectangle((int)left, (int)top, (int)width, (int)height);
    BitmapData croppedDest = destBmp.LockBits(croppedDestArea, 
          ImageLockMode.WriteOnly, BitmapImage.PixelFormat);

    // Create data array to hold bmpSource pixel data
    int stride = croppedSource.Stride;
    int numBytes = stride * (int)height;
    var srcData = new byte[numBytes];
    var destData = new byte[numBytes];

    Marshal.Copy(croppedSource.Scan0, srcData, 0, numBytes);
    //Tried creating a separate array in case that helped.
    Array.Copy(srcData, destData, srcData.Length);
    //Often hangs here with Attempted to read or write protected memory.
    Marshal.Copy(destData, 0, croppedDest.Scan0, numBytes);

    destBmp.UnlockBits(croppedDest);
    var retVal = new DocAppImage {BitmapImage = destBmp};
    destBmp.Dispose();

    //Blank the source area
    for (int y = 0; y < srcData.Length; y++)
        srcData[y] = 0xFF;

    Marshal.Copy(srcData, 0, croppedSource.Scan0, numBytes);
    _bitmapImage.UnlockBits(croppedSource);

    return retVal.bmpSource;
}

private Bitmap _bitmapImage;
public Bitmap BitmapImage
{
    get
    {
        if (_bitmapImage != null)
            return _bitmapImage;

        if (FileImage != null)
        {
            var stream = new MemoryStream(FileImage); //Fileimage=TIFF read from file.
            _bitmapImage = new Bitmap(stream);
            return _bitmapImage;
        }
        return null;
    }
    set
    {
        if (value != null)
        {

            ImageCodecInfo codecInfo = GetImageCodecInfo("TIFF");
             ... implementation to set the bitmap image.
2012-04-04 21:18
by strattonn
var destBmp = new Bitmap((int)pageWidth, (int)pageHeight); have you tried setting the destination pixelformat on this object's creation - Bryan Crosby 2012-04-04 22:20
No, I can try that - strattonn 2012-04-05 13:21
Bryan, make your comment an answer and I'll mark it as correct and comment on what I had to do - strattonn 2012-04-05 21:23


1

You may want to try specifying your PixelFormat when you create the new object.

For example:

var destBmp = new Bitmap((int)pageWidth, (int)pageHeight, PixelFormat.Format24bppRgb);
2012-04-05 21:27
by Bryan Crosby
Yes. If you copy bitmap data from one image to the other and they're not the same pixel format, some very bad things can happen - Jim Mischel 2012-04-05 21:48
The key here is my source image is 1 bit indexed but destBmp becomes 24bbp by default (graphics could not even write to an indexed image). So I just painted an array with 0xFF to blank my initial image and it's all working beautifully. Thanks - strattonn 2012-04-05 21:51
Ads