BitBlt返回false, GetLastError返回6(无效句柄)

本文关键字:返回 无效 句柄 GetLastError false BitBlt | 更新日期: 2023-09-27 18:11:45

距离我上次接触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);

BitBlt返回false, GetLastError返回6(无效句柄)

您的Win32 api调用约定是错误的。用途:

CallingConvention = CallingConvention.StdCall

最后一个参数应该是UInt32或equiv.虽然不权威,pinvoke.net是非常有用的。在本例中,它为最后一个参数定义了一个很好的枚举,以防您将对BitBlt使用任何其他光栅操作。

终于找到了我想要完成的一个确切的例子,如下:

        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 bitblts vs 100,000 . drawimages, bitblt在我的笔记本电脑上粉碎了。drawimages ~8:1。:)

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

有什么理由需要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);
    //...
}