如何在Direct2D中创建透明位图

How to create a transparent bitmap in Direct2D

本文关键字:创建 透明 位图 Direct2D      更新时间:2023-10-16

我需要使用Direct2D创建一个透明的位图,并通过使用我的设备上下文在其上绘制。

ID2D1DeviceContext1* d2dContext = ...
ID2D1Bitmap* pBitmap;
d2dContext->CreateBitmap(
    bitmapSize,
    nullptr,
    0,
    D2D1::BitmapProperties1(
        D2D1_BITMAP_OPTIONS_TARGET,
        D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
        dpiX, dpiY),
    &pBitmap);
d2dContext->BeginDraw();
d2dContext->SetTarget(pBitmap);
d2dContext->Clear(D2D1::ColorF(0, 0));
d2dContext->DrawLine(...);
hr = d2dContext->EndDraw();

不幸的是,我不能创建任何透明位图。我尝试了几种像素格式组合,包括D2D1_ALPHA_MODE_STRAIGHT,但没有成功。

有解决办法吗?

好消息Nick:你正在创建透明位图,但是你没有看到预期结果的原因与窗口创建有关。Kenny Kerr在2009年用Direct2D演示了正确的分层窗口创建。

从那以后,windows渲染方面发生了很大的变化,Win8和Win10使用了合成引擎,并允许开发人员访问DirectComposition API。因此,Kenny Kerr在2014年提供了一篇关于该主题的更新文章。

我最近的项目需要Win7支持,所以我个人坚持使用纯Direct2D。

EDIT:当然要确保你的渲染目标是正确创建的。

当我需要在Sciter中创建缓存渲染(位图)时,我是这样做的:

ID2D1RenderTarget* src = ...
d2d::asset<ID2D1BitmapRenderTarget> dst = nullptr;
// creating temp surface - compatible render target:
src->CreateCompatibleRenderTarget(sz,dst.target());
dst->BeginDraw();
dst->Clear(init_color);
... drawing on that temp surface ...
dst->EndDraw();
d2d::asset<ID2D1Bitmap> dst_bmp;
hr = dst->GetBitmap(il->d2d_bmp.target());
return dst_bmp;

此方法将位图创建委托给ID2D1RenderTarget,因此位图将始终与源兼容。代码主要用于透明的init_color。

我不会使用SetTarget(),因为它不清楚它对剪辑等的作用