距离我上次接触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);
您的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);
//...
}