0

自从我上次涉足 GDI 以来已经有几年了,但我不记得以前遇到过这样的问题。我没有遇到异常,但 BitBlt 返回 0 (False),检查 GetLastWIN32Error 显示 6。这似乎是一个无效的句柄。并且目标图像保持空白。

我也添加了对 SelectObject 的调用,但这不应该也不会影响无效句柄错误。

对我所缺少的有什么想法吗?

void MySub()
{
    var bmpSrc = new Bitmap("c:\\temp\\test.bmp", false);
    var bmpDst= new Bitmap(1000, 1000);
    var gSrc = Graphics.FromImage(bmpSrc);
    var gDst = Graphics.FromImage(bmpDst);
    IntPtr HDCSrc = gSrc.GetHdc();
    IntPtr HDCDst = gDst.GetHdc();
    if (!BitBlt(HDCDst, 0, 0, 55, 94, HDCSrc, 0, 0, SRCCOPY))
    {
        int er = Marshal.GetLastWin32Error();
        MessageBox.Show(er.ToString());
    }
    gDst.ReleaseHdc(HDCDst);
    gSrc.ReleaseHdc(HDCSrc);
    pictureBox1.Image = iDst;
}

public static long SRCCOPY = 0x00CC0020;

[DllImport("gdi32.dll", CallingConvention = CallingConvention.ThisCall, SetLastError = true)]
public static extern bool BitBlt(
     IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, long dwRop);
4

3 回答 3

1

您有错误的 Win32 API 调用约定。利用:

CallingConvention = CallingConvention.StdCall

最后一个参数也应该是 UInt32 或等效的。虽然不权威,但 pinvoke.net非常有用。在这种情况下,它为最后一个参数定义了一个很好的枚举,以防您将任何其他光栅操作与BitBlt.

于 2013-04-30T17:44:19.747 回答
1

终于设法找到了一个我试图完成的确切例子,这里是:

        var bmpSrc = new Bitmap("c:\\temp\\test.bmp");
        var bmpDst = new Bitmap(1000, 1000);

        // Get source image  in memory
        Graphics sourceImageGraphics = Graphics.FromImage(bmpDst);
        IntPtr sourceImageHDC = sourceImageGraphics.GetHdc();
        IntPtr sourceImageCDC = CreateCompatibleDC(sourceImageHDC);
        IntPtr sourceImageHandle = bmpDst.GetHbitmap();
        SelectObject(sourceImageCDC, sourceImageHandle);

        // Get overlay image in memory
        Graphics overlayImageGraphics = Graphics.FromImage(bmpSrc);
        IntPtr overlayImageHDC = overlayImageGraphics.GetHdc();
        IntPtr overlayImageCDC = CreateCompatibleDC(overlayImageHDC);
        IntPtr overlayImageHandle = bmpSrc.GetHbitmap();
        SelectObject(overlayImageCDC, overlayImageHandle);

        for (int x = 0; x < _Iterations; x++)
                if (!BitBlt(sourceImageHDC, 0, 0, 55, 94, overlayImageCDC, 0, 0, TernaryRasterOperations.SRCCOPY))
                {
                    var er = Marshal.GetLastWin32Error();
                    MessageBox.Show(er.ToString());
                }

        // Release source Image memory.
        DeleteDC(sourceImageCDC);
        DeleteObject(sourceImageHandle);
        sourceImageGraphics.ReleaseHdc(sourceImageHDC);
        sourceImageGraphics.Dispose();

        // Release overlay Image memory.
        DeleteDC(overlayImageCDC);
        DeleteObject(overlayImageHandle);
        overlayImageGraphics.ReleaseHdc(overlayImageHDC);
        overlayImageGraphics.Dispose();

        pictureBox1.Image = bmpDst;

超过 100,000 个 bitblt 与 100,000 个 .DrawImages,bitblt 在我的笔记本电脑上碾压 .DrawImages ~8:1。:)

于 2013-05-01T02:02:18.090 回答
0

好的,所以这可能是一条评论,但由于有代码,我在这里发布:

有什么理由需要 p/invoke 吗?有什么问题:

using(var bmpSrc = new Bitmap("c:\\temp\\test.bmp", false))
using(var bmpDst = new Bitmap(1000, 1000))
using(var gDst = Graphics.FromImage(bmpDst))
{
    gDst.DrawImage(bmpSrc,0,0,55,94);
    //...
}
于 2013-04-30T17:44:10.567 回答