Marshal.Copy / UnlockBits挂起

时间:2012-04-04 21:18:50

标签: c# .net wpf graphics

用户选择图像的一部分进行剪切和粘贴操作。我创建一个新的位图,将所选部分粘贴到新图像中,擦除源阵列并将其粘贴回旧图像。工作但至少有一半的时间它挂起尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

有任何想法或帮助吗?

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.

1 个答案:

答案 0 :(得分:1)

您可能希望在创建新对象时尝试指定PixelFormat

例如:

var destBmp = new Bitmap((int)pageWidth, (int)pageHeight, PixelFormat.Format24bppRgb);