BitBlt的code不工作

BitBlt的code不工作

本文介绍了BitBlt的code不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用这个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不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 18:32