C# BitBlt返回false,GetLastError返回6(无效句柄)?
自从我上次进入GDI已经有几年了,但我不记得以前有过这样的问题。我没有收到异常,但BitBlt返回0(False),检查GetLastWIN32Error显示6。这似乎是一个无效的句柄。并且目标图像保持空白 我还添加了对SelectObject的调用,但这不应该也不会影响无效句柄错误 有没有想过我错过了什么C# BitBlt返回false,GetLastError返回6(无效句柄)?,c#,gdi,bitblt,C#,Gdi,Bitblt,自从我上次进入GDI已经有几年了,但我不记得以前有过这样的问题。我没有收到异常,但BitBlt返回0(False),检查GetLastWIN32Error显示6。这似乎是一个无效的句柄。并且目标图像保持空白 我还添加了对SelectObject的调用,但这不应该也不会影响无效句柄错误 有没有想过我错过了什么 void MySub() { var bmpSrc = new Bitmap("c:\\temp\\test.bmp", false); var bmpDst= new Bi
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);
好的,这可能是一条评论,但由于有代码,我在这里发布: 有什么理由需要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);
//...
}
Win32 API的调用约定错误。使用:
CallingConvention = CallingConvention.StdCall
最后一个参数应该是UInt32或等效参数。虽然不是权威性的,但非常有用。在本例中,它为最后一个参数定义了一个很好的枚举,以防您在使用任何其他光栅操作时使用
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;
var bmpSrc=新位图(“c:\\temp\\test.bmp”);
var bmpDst=新位图(10001000);
//在内存中获取源图像
Graphics sourceImageGraphics=Graphics.FromImage(bmpDst);
IntPtr sourceImageHDC=sourceImageGraphics.GetHdc();
IntPtr sourceImageCDC=CreateCompatibleDC(sourceImageHDC);
IntPtr sourceImageHandle=bmpDst.GetHbitmap();
选择对象(sourceImageCDC、sourceImageHandle);
//在内存中获取覆盖图像
Graphics overlayImageGraphics=Graphics.FromImage(bmpSrc);
IntPtr overlayImageHDC=overlayImageGraphics.GetHdc();
IntPtr overlayImageCDC=CreateCompatibleDC(overlayImageHDC);
IntPtr overlayImageHandle=bmpSrc.GetHbitmap();
选择对象(overlayImageCDC、overlayImageHandle);
对于(int x=0;x<_迭代;x++)
if(!BitBlt(sourceImageHDC,0,0,55,94,overlayImageCDC,0,0,TernaryRasterOperations.SRCCOPY))
{
var er=Marshal.GetLastWin32Error();
Show(er.ToString());
}
//释放源映像内存。
DeleteDC(sourceImageCDC);
DeleteObject(sourceImageHandle);
sourceImageGraphics.ReleaseHdc(sourceImageHDC);
sourceImageGraphics.Dispose();
//释放覆盖图像内存。
DeleteDC(overlayImageCDC);
DeleteObject(overlayImageHandle);
overlayImageGraphics.ReleaseHdc(overlayImageHDC);
overlayImageGraphics.Dispose();
pictureBox1.Image=bmpDst;
超过100000比特比特,而不是100000比特。DrawImages,bitblt正在崩溃。DrawImages~8:1在我的笔记本电脑上。:) 好问题!事实上,我看到了图形的性能问题。绘制。。。对于渲染的数量和我们访问的用户数量。我的计划是比较DrawImage和直接调用BitBlt的性能,看看是否值得继续。另一个重要的观点是,我的反应受到我对这一变化的全面影响的理解不足的限制,但是使用CallingConvention.StdCall会导致BitBlt调用出现异常:对PInvoke函数“Form1::BitBlt”的调用导致堆栈不平衡。这可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。如果使用StdCall,我是否缺少其他配置来确保兼容性?感谢指向pinvoke.net的指针,这对正确定义bitblt非常有帮助!