和 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 格式

如何融合两个 16 位图像

如何在两个片段之间传递位图? (我正在使用 Android 导航组件)

加速位图灰度转换,OpenMP 是 C# 中的一个选项吗?

从两点裁剪图像(C#)

合并两个位图的问题