Direct2D:在位图中捕获对话框背景 [英] Direct2D: Capturing a dialog background in a bitmap

查看:81
本文介绍了Direct2D:在位图中捕获对话框背景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将自定义MFC控件从GDI +转换为Direct2D.该控件位于具有位图背景的对话框中.我需要捕获对话框背景位于控件下的部分,以便可以在控件的OnPaint()函数中呈现背景.有没有一种方法可以将对话框背景捕获到Direct2D中的位图?

在GDI +中,这很简单.您只需创建一个与对话框dc兼容的dc.创建一个兼容的位图,将其加载到DC中,然后将对话框DC的BitBlt加载到兼容的DC中.然后可以使用GDI +绘制位图.

我曾尝试在Direct2D中执行类似的操作,但无法正常工作.我创建了一个ID2D1DCRenderTarget对象,然后将该对象绑定到对话框dc.然后,我调用ID2D1DCRenderTarget :: CreateCompatibleRenderTarget()来创建一个ID2D1BitmapRenderTarget对象.然后,我可以在对象上调用GetBitmap(),但它似乎没有返回可渲染到自定义控件上的有效位图?

I''m converting a custom MFC control from GDI+ to Direct2D. The control sits on a dialog which has a bitmap background. I need to capture the portion of the dialog background which sits under the control so that I can render the background in the control''s OnPaint() function. Is there a way to capture the dialog background to a bitmap in Direct2D?

In GDI+ this is pretty straight forward. You just create a dc compatible with the dialog dc. Create a compatible bitmap, load it into the dc and then BitBlt the dialog dc into the compatible dc. The bitmap can then be drawn using GDI+.

I''ve tried doing something similar in Direct2D but it''s not working. I created a ID2D1DCRenderTarget object and then bound the object to the dialog dc. I then called ID2D1DCRenderTarget::CreateCompatibleRenderTarget() which creates a ID2D1BitmapRenderTarget object. I can then call GetBitmap() on the object but it doesn''t seem to return a valid bitmap that I can render onto the custom control?

推荐答案

好吧,终于成功了.对于其他感兴趣的人,这里是从设备上下文捕获图像并将其渲染到Direct2D渲染目标中所需的步骤.就我而言,我想从具有位图背景的MFC CDialogEx对话框窗口中捕获图像.

第一步需要使用GDI将位图从对话框设备上下文复制到存储设备上下文.这可以使用CreateCompatibleDC(),CreateCompatibleBitmap()和BitBlt()完成.我将结果位图存储在MFC CBitmap对象中.
现在的技巧是将位图放入ID2D1Bitmap对象中,以便我们可以将其渲染到渲染目标.这是使用Windows Imaging Component(WIC)实现的.

首先,调用IWICImagingFactory :: CreateBitmapFromHBITMAP(),传入我们之前创建的CBitmap.这将创建一个IWICBitmap对象.现在需要将IWICBitmap对象转换为32bppPBGRA像素格式.这是使用IWICFormatConverter对象完成的.调用IWICFormatConverter :: Initialize(),以指定先前创建的IWICBitmap对象.

最后,调用ID2D1RenderTarget :: CreateBitmapFromWicBitmap(),传入上面创建的IWICFormatConverter对象.这将创建一个ID2D1Bitmap对象,现在可以在渲染目标中对其进行绘制.

代码片段如下所示:


Ok, finally got this working. For anyone else who is interested, here are the steps required to capture the image from a device context and render it into a Direct2D render target. In my case I wanted to capture the image from an MFC CDialogEx dialog window that had a bitmap background.

The first steps require the use of GDI to copy a bitmap from the dialog device context to a memory device context. This can be done using CreateCompatibleDC(), CreateCompatibleBitmap() and BitBlt(). I stored the resulting bitmap in an MFC CBitmap object.

The trick now is to get the bitmap into a ID2D1Bitmap object so that we can render it to the render target. This is achieved using the Windows Imaging Component (WIC).

First, call IWICImagingFactory::CreateBitmapFromHBITMAP(), passing in the CBitmap we created earlier. This will create an IWICBitmap object. The IWICBitmap object now needs to be converted to a 32bppPBGRA pixel format. This is done using a IWICFormatConverter object. Call IWICFormatConverter::Initialize() specifying the IWICBitmap object created previously.

Finally, call ID2D1RenderTarget::CreateBitmapFromWicBitmap(), passing in the IWICFormatConverter object created above. This will create an ID2D1Bitmap object that can now be drawn in the render target.

A snippet of code is shown below:


CClientDC dcParent(GetParent());
CRect rectClient;
CRect rectWindow;
CDC dcBackground;
CBitmap *pOldBitmap = NULL;
CBitmap DialogBitmap;
HRESULT hr = E_FAIL;
CComPtr<IWICBitmap> pDialogBitmap = NULL;

m_pParentBitmap.Release();
GetWindowRect(rectWindow);
GetParent()->ScreenToClient(rectWindow);
GetClientRect(rectClient);

dcBackground.CreateCompatibleDC(&dcParent);
DialogBitmap.CreateCompatibleBitmap(&dcParent, rectClient.Width(), rectClient.Height());
pOldBitmap = dcBackground.SelectObject(&DialogBitmap);

dcBackground.BitBlt(0, 0, rectClient.Width(), rectClient.Height(), &dcParent, rectWindow.left, rectWindow.top, SRCCOPY);
dcBackground.SelectObject(pOldBitmap);

// Note that the WICBitmapAlphaChannelOption is very important. If we don''t set it to a value that is compatible
// with the render target where we intend to draw the bitmap then a black bitmap will be drawn.
hr = theApp.g_pWICFactory->CreateBitmapFromHBITMAP(DialogBitmap, NULL, WICBitmapIgnoreAlpha/*WICBitmapUsePremultipliedAlpha*/, &pDialogBitmap);
if (SUCCEEDED(hr))
{
    // Convert the dialog bitmap to a 32bppPBGRA pixel format. Before Direct2D can use an image, it must be converted
    // to the 32bppPBGRA pixel format. To convert the image format, use the CreateFormatConverter method to create
    // an IWICFormatConverter object. Once created, use the Initialize method to perform the conversion.
    CComPtr<IWICFormatConverter> pFormatConverter = NULL;
    hr = pWICFactory->CreateFormatConverter(&pFormatConverter);
    if (SUCCEEDED(hr))
    {
        // dither, pIPalette, alphaThresholdPercent, and paletteTranslate are used to mitigate color loss when converting
        // to a reduced bit-depth format. We do not need to do this so we use the following parameters:
        // dither set to WICBitmapDitherTypeNone,
        // pIPalette set to NULL,
        // alphaThresholdPercent set to 0.0f,
        // and paletteTranslate set to WICBitmapPaletteTypeCustom
        hr = pFormatConverter->Initialize(pDialogBitmap,                    // Input bitmap to convert
                                          GUID_WICPixelFormat32bppPBGRA,    // Destination pixel format
                                          WICBitmapDitherTypeNone,          // Specified dither pattern
                                          NULL,                             // Specify a particular palette
                                          0.0f,                             // Alpha threshold
                                          WICBitmapPaletteTypeCustom);      // Palette translation type.
        if (SUCCEEDED(hr))
        {
            hr = pRenderTarget->CreateBitmapFromWicBitmap(pFormatConverter, NULL, &m_pParentBitmap);
            m_bParentBackgroundCaptured = true;
        }
    }
}


这篇关于Direct2D:在位图中捕获对话框背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆