和 C# 中的两个位图
Posted
技术标签:
【中文标题】和 C# 中的两个位图【英文标题】:AND two bitmaps in C# 【发布时间】:2011-04-10 09:37:16 【问题描述】:我正在尝试 AND 两个这样的位图:
[DllImport("gdi32.dll")] 公共静态外部 int SetROP2(IntPtr hDC, int nDrawMode); 常量 int SRCAND = 0x008800C6; // AND 光栅运算。 锁定(g.Clip) IntPtr pDC = g.GetHdc (); SetROP2 (pDC, SRCAND); g.DrawImageUnscaled(currentBitmap, bound.Location); g.ReleaseHdc (pDC);但我从 Draw 语句中得到一个“对象当前正在其他地方使用”异常。在 Draw 语句运行之前移动 ReleaseHdc 语句,但不使用指定的光栅操作。
LockBits 方法太慢了,因为它复制整个位图两次,其中一个位图很大,并且每秒必须发生多次。
有什么方法可以欺骗 .NET 到 ANDing 位图?
【问题讨论】:
【参考方案1】: lock (g.Clip)
这行不通。您收到此异常是因为您在多个线程中使用位图。我猜另一个正在绘制位图的线程。为了使这项工作,您必须确保两个线程不能同时使用位图。这确实需要 lock 关键字。但在 same 锁定对象上。您使用的 Graphics 实例将不一样。锁不起作用。
创建两个线程都使用的专用锁定对象。
【讨论】:
我在两个可以绘制的地方都使用了相同的锁定对象,但我仍然遇到同样的错误。如果我拨打 SetROP2 电话,它会起作用。如果问题是多个线程使用相同的位图或图形对象,问题是否仍然存在? 找到了解决方案:在这种情况下,为位图背景使用透明颜色会产生相同的效果。感谢汉斯的建议。【参考方案2】:尽管您找到了解决方法,但值得注意的是异常的实际来源。 GDI 和 GDI+ 操作不能交错 - 一个或另一个可以同时操作,但不能同时操作。
在您的代码中,调用 g.GetHdc()
会将 Graphics 对象切换到新创建的 HDC 可用于 GDI 渲染的状态。在调用g.ReleaseHdc()
之前,Graphics 对象将处于“使用中”。至此,HDC 被销毁,Graphics 对象可以再次用于渲染。
注意到调用 GetHdc()
返回的 HDC 是新创建的,并且只存在到调用 ReleaseHdc()
之前,它被销毁,很明显为什么 ROP 不应用于稍后执行的操作图形对象。
如果您需要使用 GDI ROP,则必须在纯 GDI 上下文中执行所有相关的渲染 - 使用 Bitmap.GetHbitmap()
来获取必要的句柄。请注意,与Graphics.GetHdc()
类似,HBITMAP 是从Bitmap
新创建的,但不与它共享任何状态。
有关 GDI/GDI+ 互操作的更多详细信息,请参见 KB 311221
【讨论】:
以上是关于和 C# 中的两个位图的主要内容,如果未能解决你的问题,请参考以下文章
如何在 c# 中的 iTextSharp pdf 中将位图显示为 jpeg 格式