在不安全的环境中编辑位图 - 如何避免不稳定?
我试图在不安全的上下文中使用位图,并且发现其中的不稳定,例如,程序第一次运行但第二次失败。 这是代码:
private static void RenderBitmap(Graphics g)
{
const int width = 150, height = 150;
using (Bitmap bmp = new Bitmap(width, height,
System.Drawing.Imaging.PixelFormat.Format24bppRgb))
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
NativeMethods.RenderText(Graphics.FromImage(bmp).GetHdc(), bmpData.Scan0,
"This works only first time round", "Segoe", 10,
new RGBA(255, 0, 0, 255), width, height);
bmp.UnlockBits(bmpData);
g.DrawImage(bmp, new Rectangle(width, height, width, -height));
}
}
看到这不起作用,我有几个问题。 如果本机 RenderText 方法直接操作位图内存,我所做的事情是否安全且正确? 我从位图中获取 HDC 的方法是否正确,或者我应该使用从绘图方法传递的参数 g 吗?
我收到的错误是这样的:
System.AccessViolationException 是 未处理的消息=“尝试读取 或写保护内存。 这是 通常表明其他记忆 已腐败。”
I'm trying to use a bitmap in an unsafe context, and am seeing instability in that, e.g., the program runs the first time round but fails the second. Here is the code:
private static void RenderBitmap(Graphics g)
{
const int width = 150, height = 150;
using (Bitmap bmp = new Bitmap(width, height,
System.Drawing.Imaging.PixelFormat.Format24bppRgb))
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
NativeMethods.RenderText(Graphics.FromImage(bmp).GetHdc(), bmpData.Scan0,
"This works only first time round", "Segoe", 10,
new RGBA(255, 0, 0, 255), width, height);
bmp.UnlockBits(bmpData);
g.DrawImage(bmp, new Rectangle(width, height, width, -height));
}
}
Seeing how this isn't working, I have a few questions. Is what I'm doing safe and correct, provided the native RenderText
method manipulates the bitmap memory directly? Is my way of getting HDC
from the bitmap correct, or should I use the parameter g
that was passed from a drawing method?
The error I'm getting is this:
System.AccessViolationException was
unhandled Message="Attempted to read
or write protected memory. This is
often an indication that other memory
is corrupt."
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
NativeMethods.RenderRext
方法无法安全地处理位图数据,因为它不知道位图的扫描线有多宽,也不知道它是否颠倒存储在内存中。 这些症状表明该方法正在位图之外写入内存,覆盖应用程序中需要的其他内容。BitmapData.Stride
属性包含该方法处理数据所需的信息。 它包含以字节为单位的扫描线宽度,如果它为负数,则意味着位图在内存中存储颠倒。 简单来说Scan0就是第一条扫描线的地址,Scan0+Stride就是第二条扫描线的地址。The
NativeMethods.RenderRext
method can't safely work with the bitmap data, as it doesn't know how wide the scan lines of the bitmap is, and if it is stored upside down in memory or not. The symptoms suggests that the method is writing to memory outside the bitmap, overwriting something else that you need in your application.The
BitmapData.Stride
property has the information that the method needs to work with the data. It contains the scan line width in bytes, and if it's negative it means that the bitmap is stored upside down in memory. Simply Scan0 is the address of the first scan line, and Scan0 + Stride is the address of the second scan line.也许这是一个愚蠢的问题,但是为什么不使用.NET 自带的 TextRenderer 类而不是使用 p/invoke 呢?
http://msdn.microsoft.com/en-us/library/4ftkekek。 aspx
-Oisin
Maybe this is a silly question, but why don't you use the TextRenderer class that comes with .NET instead of using p/invoke?
http://msdn.microsoft.com/en-us/library/4ftkekek.aspx
-Oisin
好吧,在经历了很多痛苦和痛苦之后,我找到了一个解决方案:我没有传递要填充的内存缓冲区,而是传递了要渲染的设备上下文(HDC)。 到目前为止似乎正在工作!
感谢所有回答的人。
Well, after much pain and suffering, I found a solution: instead of passing in a memory buffer to be filled in, I passed a device context (HDC) to be rendered into. Seems to be working so far!
Thanks to all who answered.