C# Marshal.Copy/UnlockBits挂起
用户选择图像的一部分进行剪切和粘贴操作。我创建一个新位图,将选定部分粘贴到新图像中,擦除源数组并将其粘贴回旧图像中。可以工作,但至少有一半的时间是在试图读取或写入受保护内存时挂起的。这通常表示其他内存已损坏 有什么想法或帮助吗C# Marshal.Copy/UnlockBits挂起,c#,.net,wpf,graphics,C#,.net,Wpf,Graphics,用户选择图像的一部分进行剪切和粘贴操作。我创建一个新位图,将选定部分粘贴到新图像中,擦除源数组并将其粘贴回旧图像中。可以工作,但至少有一半的时间是在试图读取或写入受保护内存时挂起的。这通常表示其他内存已损坏 有什么想法或帮助吗 public BitmapSource CutToNew(double left, double top, double width, double height, double pageWidth, double pageHeight) { var destBm
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.
public BitmapSource CutToNew(双倍左、双倍顶、双倍宽、双倍高、双倍页宽、双倍页高)
{
var destBmp=新位图((int)pageWidth,(int)pageHeight);
var g=Graphics.FromImage(destBmp);
g、 FillRectangle(新的SolidBrush(颜色为白色),0,0,
(int)页面高度,(int)页面宽度);
g、 处置();
var crapedArea=新矩形((int)左,(int)顶,(int)宽,(int)高);
BitmapData croppedSource=\u bitmapImage.LockBits(croppedArea,
ImageLockMode.ReadWrite,BitmapImage.PixelFormat);
var crapedestarea=新矩形((int)左,(int)顶,(int)宽,(int)高);
BitmapData CroppedTest=destBmp.LockBits(CroppedTestArea,
ImageLockMode.WriteOnly、BitmapImage.PixelFormat);
//创建数据数组以保存bmpSource像素数据
int stride=crappedsource.stride;
int numBytes=步幅*(int)高度;
var srcData=新字节[numBytes];
var destData=新字节[numBytes];
Marshal.Copy(crappedsource.Scan0,srcData,0,numBytes);
//尝试创建一个单独的数组,以防有所帮助。
Copy(srcData、destData、srcData.Length);
//经常挂起此处,试图读取或写入受保护的内存。
Marshal.Copy(destData,0,crappeddest.Scan0,numBytes);
destBmp.UnlockBits(crappedtest);
var retVal=new DocAppImage{BitmapImage=destBmp};
destBmp.Dispose();
//空白源区域
对于(int y=0;y
创建新对象时,您可能需要尝试指定像素格式
例如:
var destBmp = new Bitmap((int)pageWidth, (int)pageHeight, PixelFormat.Format24bppRgb);
var destBmp=新位图((int)pageWidth,(int)pageHeight)
您是否尝试过在创建此对象时设置目标像素格式?Bryan,将您的注释作为答案,我会将其标记为正确,并对我必须执行的操作进行注释。是的。如果您将位图数据从一个图像复制到另一个图像,并且它们不是相同的像素格式,则可能会发生一些非常糟糕的事情。这里的关键是我的源图像是1位索引,但默认情况下destBmp变成24bbp(图形甚至无法写入索引图像)。因此,我只使用0xFF绘制了一个数组以清空我的初始图像,所有这些都工作得很好。谢谢。