- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一些代码有错误“AccessViolationException 未被用户代码处理:试图读取或写入 protected 内存...”
违规函数的精简版如下:
protected override void OnPaint(PaintEventArgs pe)
{
if ((updatingFastBackground) || (Calculating)) return; //ADDED FOR DEBUGGING, SEE BELOW
BitmapData canvasData = Canvas.LockBits(new Rectangle(Point.Empty, Canvas.Size), ImageLockMode.WriteOnly, FastPixelFormat);
BitmapData fbgData = fastBackground.LockBits(new Rectangle(Point.Empty, fastBackground.Size), ImageLockMode.ReadOnly, FastPixelFormat);
try
{
unsafe
{
byte* canvasDataScan0 = (byte*)canvasData.Scan0.ToPointer();
byte* fbgDataScan0 = (byte*)fbgData.Scan0.ToPointer();
Rectangle spriteBounds = new Rectangle(Point.Empty, ButtonImages.ImageSize);
for (int i = 0; i < ButtonImages.Images.Count; i++)
{
// Button offset location
Point l = new Point(
(int)((i % columnCount) * hStep + myIVM.Location.X),
(int)((i / columnCount) * vStep + myIVM.Location.Y));
// Paint at current location?
if (buttonPaintBounds.Contains(l))
{
BitmapData spriteData = buttonBitmaps[i].LockBits(spriteBounds, ImageLockMode.ReadOnly, FastPixelFormat);
try
{
int spriteLeft = Math.Max(l.X, 0);
int spriteRight = Math.Min(l.X + ButtonImages.ImageSize.Width, canvasData.Width);
int spriteTop = Math.Max(l.Y, 0);
int spriteBottom = Math.Min(l.Y + ButtonImages.ImageSize.Height, canvasData.Height);
int spriteWidth = spriteRight - spriteLeft;
int spriteHeight = spriteBottom - spriteTop;
byte* canvasRowLeft = canvasDataScan0 + (spriteTop * canvasData.Stride) + spriteLeft * 4;
byte* spriteRowLeft =
(byte*)spriteData.Scan0.ToPointer() +
Math.Max((spriteTop - l.Y), 0) * spriteData.Stride +
Math.Max((spriteLeft - l.X), 0) * 4;
for (int y = 0; y < spriteHeight; y++)
{
canvasRowLeft += canvasData.Stride;
spriteRowLeft += spriteData.Stride;
Byte* canvasWalk = (Byte*)canvasRowLeft;
Byte* spriteWalk = (Byte*)spriteRowLeft;
for (int x = 0; x < spriteWidth; x++)
{
if (spriteWalk[3] != 255)
{
canvasWalk[0] = (byte)(canvasWalk[0] * spriteWalk[3] / 255 + spriteWalk[0]);
canvasWalk[1] = (byte)(canvasWalk[1] * spriteWalk[3] / 255 + spriteWalk[1]);
canvasWalk[2] = (byte)(canvasWalk[2] * spriteWalk[3] / 255 + spriteWalk[2]);
}
canvasWalk += 4;
spriteWalk += 4;
}
}
thesePoints.Add(l);
}
finally
{
buttonBitmaps[i].UnlockBits(spriteData);
}
}
错误发生在线路上:
canvasWalk[0] = (byte)(canvasWalk[0] * spriteWalk[3] / 255 + spriteWalk[0]);
甚至替换为:
canvasWalk[0] = 0;
迭代变量 y
和 x
每次崩溃时都有不同的值,所以这让我相信外部函数正在修改 Canvas
位图。
如果这实际上是我的问题,有没有办法防止 fastBackground
和 Canvas
被外部修改?我认为 LockBits
应该这样做...
如果这还不够回答,这里还有一些我试过的:我添加了行
if ((updatingFastBackground) || (Calculating)) return;
如果 fastBackground
Canvas
或尺寸被其他函数修改,则退出 OnPaint。
我可以使用互斥锁来防止修改位图fastBackground
和Canvas
的函数与paint (正如我认为的那样),但我宁愿以另一种方式阻止它们,因为 Canvas 是公开的,我不想要求将互斥体传递到类之外。
根据@usr 的建议,这个进一步精简的版本不会失败...一定是 PTD 错误。 (程序员太笨了)即算术错误
protected override void OnPaint(PaintEventArgs pe)
{
if ((updatingFastBackground) || (Calculating)) return; //ADDED FOR DEBUGGING, SEE BELOW
BitmapData canvasData = Canvas.LockBits(new Rectangle(Point.Empty, Canvas.Size), ImageLockMode.WriteOnly, FastPixelFormat);
BitmapData fbgData = fastBackground.LockBits(new Rectangle(Point.Empty, fastBackground.Size), ImageLockMode.ReadOnly, FastPixelFormat);
try
{
unsafe
{
byte* canvasDataScan0 = (byte*)canvasData.Scan0.ToPointer();
byte* fbgDataScan0 = (byte*)fbgData.Scan0.ToPointer();
Rectangle spriteBounds = new Rectangle(Point.Empty, ButtonImages.ImageSize);
for (int i = 0; i < ButtonImages.Images.Count; i++)
{
// Button offset location
Point l = new Point(
(int)((i % columnCount) * hStep + myIVM.Location.X),
(int)((i / columnCount) * vStep + myIVM.Location.Y));
// Paint at current location?
if (buttonPaintBounds.Contains(l))
{
BitmapData spriteData = buttonBitmaps[i].LockBits(spriteBounds, ImageLockMode.ReadOnly, FastPixelFormat);
try
{
byte* canvasRowLeft = canvasDataScan0;
byte* spriteRowLeft = (byte*)spriteData.Scan0.ToPointer();
for (int y = 0; y < 145; y++)
{
canvasRowLeft += canvasData.Stride;
spriteRowLeft += spriteData.Stride;
Byte* canvasWalk = (Byte*)canvasRowLeft;
Byte* spriteWalk = (Byte*)spriteRowLeft;
for (int x = 0; x < 145; x++)
{
if (spriteWalk[3] != 255)
{
canvasWalk[0] = 0;
canvasWalk[1] = 0;
canvasWalk[2] = 0;
}
canvasWalk += 4;
spriteWalk += 4;
}
}
thesePoints.Add(l);
}
finally
{
buttonBitmaps[i].UnlockBits(spriteData);
}
}
最佳答案
将我的评论移到答案中,因为它有助于解决问题:
LockBits 返回的缓冲区不需要 Fixed,因为它是非托管内存。你的指针算法是错误的。找到错误。创建一个简单的重现来帮助找到错误。
关于c# - lockbits 是否需要固定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14716194/
我有一些代码有错误“AccessViolationException 未被用户代码处理:试图读取或写入 protected 内存...” 违规函数的精简版如下: protected override
我有一个方法需要尽可能快,它使用不安全的内存指针,这是我第一次尝试这种类型的编码,所以我知道它可能会更快。 /// /// Copies bitmapdata from one bi
使用 GetPixel 和 SetPixel 很简单,但速度很慢,所以我尝试使用 LockBits。 我很久以前就用过这种方法来比较两张图片: public static Bitmap FastCom
首先,我会指出我将接受 C# 或 VB.NET 解决方案。 我正在尝试重构这段旧代码,以避免使用 GetPixel/SetPixel 方法的坏习惯和性能低下: Public Function Cha
按照 Bob Powell 关于 LockBits 的教程,我将以下代码放入 C# 2010 Visual Studio Express 中: System.Drawing.Imaging.Bitma
我正在尝试使用 Lockbits 写出灰度图像,我当前的代码看起来是 /// /// Save the content of the FrameProc out to a bitmap /// p
我正在使用以下代码来锁定位图的矩形区域 Recangle rect = new rect(X,Y,width,height); BitmapData bitmapData = bitmap.LockB
我在将一些代码从 Bitmap.GetPixel 更改为使用 LockBits 返回的直接像素缓冲区时遇到问题。与 GetPixel 相比,LockBits 返回的数据似乎确实给了我不同的颜色值。 这
我在 Android 上的程序使用的算法使用了很多 setPixel 和 getPixel,因此,它非常慢。在 .NET 上,我可以使用 LockBits 使其更快。 Java 或 Android 上
MSDN 引用:[1] http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx#Y1178 从链接中可以看出,第一个参数将“指定要锁定的位图部分”,
我正在处理由摄像机拍摄的 10 兆像素图像。 目的是在矩阵(二维数组)中注册每个像素的灰度值。 我第一次使用 GetPixel 但花了 25 秒才完成。现在我使用 Lockbits,但仍然需要 10
在部署应用程序之前,我使用 XP 虚拟机和 Vista 虚拟机对应用程序进行冒烟测试。这两个虚拟机都使用 32 位颜色。不确定这是否有什么区别,但我正在使用 VirtualBox。每台机器还分配有 2
我想使用 LockBits 方法更快地比较相似图像,如下所示 using System; using System.Drawing; using System.Drawing.Imaging; usi
我最近经常使用锁定位图,并且不断收到“试图访问无效内存”错误。这主要是因为位图已在内存中移动。有些人使用 GCHandle.Alloc() 在 CLR 中分配内存并固定它。 Bitmap.LockBi
我做了一个实现边缘检测算法的程序,但需要很长时间来处理。我读过有关使用锁位和不安全状态而不是 getpixel 和 setpixel 的信息,但我仍然不明白如何使用它。 这是我的示例代码: priva
使用 MS Visual Studio 2013,具有以下代码: using System; using System.Collections.Generic; using System.Linq;
我正在从一张 1bpp 索引图像剪切并粘贴到一张新图像。 一切正常,直到起始像素是 8 的除数。在下面的代码中,步幅等于相对于矩形宽度的值,直到我达到字节边界。那么步幅等于整个页面的宽度。 var c
我的程序是用 C# 编写的,在低级别上使用位图进行操作。一切正常,但有时(很少见,但稳定)出现“通用 GDI+ 异常”异常,并且很难重现这种情况。 函数 LockBits() 和 UnLockBits
我最近经常使用锁定位图,并且不断收到“试图访问无效内存”错误。这主要是因为位图已在内存中移动。有些人使用 GCHandle.Alloc() 在 CLR 中分配内存并固定它。 Bitmap.LockBi
编辑:非常感谢您的回复。我在这里最需要的是示例代码,用于说明我对嵌套循环中的几行代码所做的工作,因为这在 GetPixel/SetPixel 中是有效的,但也是我无法使用 Lockbits 正确工作的
我是一名优秀的程序员,十分优秀!