问题描述
我试图用这个code到A 位图
直接绘制到图片框
:
BMP位=(位图)Bitmap.FromFile(@C:\ Users \用户肯\桌面\ Load2.bmp);
图形grDest = Graphics.FromHwnd(pictureBox1.Handle);
图形grSrc = Graphics.FromImage(BMP);
IntPtr的hdcDest = grDest.GetHdc();
IntPtr的hdcSrc = grSrc.GetHdc();
的BitBlt(hdcDest,0,0,pictureBox1.Width,pictureBox1.Height,
hdcSrc,0,0,(UINT)TernaryRasterOperations.SRCCOPY); // 0x00CC0020
grDest.ReleaseHdc(hdcDest);
grSrc.ReleaseHdc(hdcSrc);
但不是渲染位图
的内容,它只是吸引了近黑色的固体块。我是pretty的确定问题是与源的hDC,因为如果我改变SRCCOPY白度在上述code,它吸引了坚实的白色块,符合市场预期。
请注意:这下段工作得很好,所以没有什么不对的位图本身的:
BMP位=(位图)Bitmap.FromFile(@C:\ Users \用户肯\桌面\ Load2.bmp);
pictureBox1.Image = BMP;
这是因为一个设备上下文包含一个1x1的黑位,直到选择对象
被使用。无论出于何种原因, Graphics.FromImage
是给你的设备上下文与位图兼容,但它不会自动选择位图到设备上下文。
下面code会使用选择对象
。
您应该,当然,使用托管 Graphics.DrawImage
而不是的BitBlt
如果可能的话,但我相信你有一个很好的理由使用的BitBlt
。
私人无效抽奖()
{
使用(BMP位=(位图)Bitmap.FromFile(@C:\贾森\ forest.jpg))
使用(图形grDest = Graphics.FromHwnd(pictureBox1.Handle))
使用(图形grSrc = Graphics.FromImage(BMP))
{
IntPtr的hdcDest = IntPtr.Zero;
IntPtr的hdcSrc = IntPtr.Zero;
IntPtr的HBITMAP = IntPtr.Zero;
IntPtr的hOldObject = IntPtr.Zero;
尝试
{
hdcDest = grDest.GetHdc();
hdcSrc = grSrc.GetHdc();
HBITMAP = bmp.GetHbitmap();
hOldObject =选择对象(hdcSrc,HBITMAP);
如果(hOldObject == IntPtr.Zero)
抛出新Win32Exception();
如果(!的BitBlt(hdcDest,0,0,pictureBox1.Width,pictureBox1.Height,
hdcSrc,0,0,0x00CC0020U))
抛出新Win32Exception();
}
最后
{
如果(hOldObject = IntPtr.Zero!)选择对象(hdcSrc,hOldObject);
如果(HBITMAP = IntPtr.Zero!)DeleteObject(HBITMAP);
如果(hdcDest = IntPtr.Zero!)grDest.ReleaseHdc(hdcDest);
如果(hdcSrc = IntPtr.Zero!)grSrc.ReleaseHdc(hdcSrc);
}
}
}
[的DllImport(GDI32.DLL,入口点=选择对象)]
公共静态外部System.IntPtr选择对象(
[在()] System.IntPtr HDC,
[在()] System.IntPtr h)条;
[的DllImport(GDI32.DLL,入口点=DeleteObject)]
[返回:的MarshalAs(UnmanagedType.Bool)
公共静态的extern BOOL DeleteObject(
[在()] System.IntPtr HO);
[的DllImport(GDI32.DLL,入口点=的BitBlt)
[返回:的MarshalAs(UnmanagedType.Bool)
公共静态的extern BOOL的BitBlt(
[在()] System.IntPtr HDC,INT X,INT Y,INT CX,INT CY,
[在()] System.IntPtr hdcSrc,INT X1,Y1 INT,UINT ROP);
I'm trying to use this code to draw a Bitmap
directly onto a PictureBox
:
Bitmap bmp = (Bitmap)Bitmap.FromFile(@"C:\Users\Ken\Desktop\Load2.bmp");
Graphics grDest = Graphics.FromHwnd(pictureBox1.Handle);
Graphics grSrc = Graphics.FromImage(bmp);
IntPtr hdcDest = grDest.GetHdc();
IntPtr hdcSrc = grSrc.GetHdc();
BitBlt(hdcDest, 0, 0, pictureBox1.Width, pictureBox1.Height,
hdcSrc, 0, 0, (uint)TernaryRasterOperations.SRCCOPY); // 0x00CC0020
grDest.ReleaseHdc(hdcDest);
grSrc.ReleaseHdc(hdcSrc);
but instead of rendering the Bitmap
's contents it just draws a solid block of nearly-black. I'm pretty sure the problem is with the source hDC, because if I change SRCCOPY to WHITENESS in the above code, it draws a solid white block, as expected.
Note: this next snippet works fine, so there's nothing wrong with the bitmap itself:
Bitmap bmp = (Bitmap)Bitmap.FromFile(@"C:\Users\Ken\Desktop\Load2.bmp");
pictureBox1.Image = bmp;
This is because a device context contains a 1x1 black bitmap until SelectObject
is used. For whatever reason, Graphics.FromImage
is giving you a device context that is compatible with the bitmap, but it does not automatically select the bitmap into the device context.
The following code will use SelectObject
.
You should, of course, use the managed Graphics.DrawImage
instead of BitBlt
if possible, but I assume that you have a good reason for using BitBlt
.
private void Draw()
{
using (Bitmap bmp = (Bitmap)Bitmap.FromFile(@"C:\Jason\forest.jpg"))
using (Graphics grDest = Graphics.FromHwnd(pictureBox1.Handle))
using (Graphics grSrc = Graphics.FromImage(bmp))
{
IntPtr hdcDest = IntPtr.Zero;
IntPtr hdcSrc = IntPtr.Zero;
IntPtr hBitmap = IntPtr.Zero;
IntPtr hOldObject = IntPtr.Zero;
try
{
hdcDest = grDest.GetHdc();
hdcSrc = grSrc.GetHdc();
hBitmap = bmp.GetHbitmap();
hOldObject = SelectObject(hdcSrc, hBitmap);
if (hOldObject == IntPtr.Zero)
throw new Win32Exception();
if (!BitBlt(hdcDest, 0, 0, pictureBox1.Width, pictureBox1.Height,
hdcSrc, 0, 0, 0x00CC0020U))
throw new Win32Exception();
}
finally
{
if (hOldObject != IntPtr.Zero) SelectObject(hdcSrc, hOldObject);
if (hBitmap != IntPtr.Zero) DeleteObject(hBitmap);
if (hdcDest != IntPtr.Zero) grDest.ReleaseHdc(hdcDest);
if (hdcSrc != IntPtr.Zero) grSrc.ReleaseHdc(hdcSrc);
}
}
}
[DllImport("gdi32.dll", EntryPoint = "SelectObject")]
public static extern System.IntPtr SelectObject(
[In()] System.IntPtr hdc,
[In()] System.IntPtr h);
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteObject(
[In()] System.IntPtr ho);
[DllImport("gdi32.dll", EntryPoint = "BitBlt")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool BitBlt(
[In()] System.IntPtr hdc, int x, int y, int cx, int cy,
[In()] System.IntPtr hdcSrc, int x1, int y1, uint rop);
这篇关于BitBlt的code不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!