在 MFC 中使用 Direct2D 将 svg 文件转换为位图

问题描述 投票:0回答:1

我想将 svg 文件转换为位图。我读到 Direct2D 支持加载和使用 svg 文件。在MFC中如何使用?

我尝试了 Direct2D SVG 图像渲染示例中的代码。但无法在 MFC 窗口上渲染/绘制。

我想为各种 MFC 控件小部件使用转换后的位图。

c++ svg mfc directx direct2d
1个回答
0
投票

这里是一个控制台应用程序示例,它使用 Direct2D 从支持透明度的 SVG 文件创建 MFC CBitmap。由于 CBitmap 是基于 GDI/HDC 的,因此我使用了 ID2D1DCRenderTarget 接口 .

注意:没有进行错误检查,我只是返回 HRESULT 值:

#define _AFXDLL // depends on your compilation options
#include <WinSock2.h> // MFC...
#include <windows.h>
#include <afxwin.h> // CBitmap
#include <atlbase.h>
#include <atlcom.h> // CComPtr
#include <d2d1.h>
#include <d2d1_3.h> // ID2D1DeviceContext5

#pragma comment(lib, "d2d1")

void BuildSvgAsCBitmap(int width, int height)
{
    // initialize Direct2D
    D2D1_FACTORY_OPTIONS options = { D2D1_DEBUG_LEVEL_INFORMATION }; // remove this in release
    CComPtr<ID2D1Factory> factory;
    auto hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, IID_ID2D1Factory, &options, (void**)&factory);

    // create an in-memory bitmap
    BITMAPINFO bitmapInfo = {};
    bitmapInfo.bmiHeader.biSize = sizeof(bitmapInfo.bmiHeader);
    bitmapInfo.bmiHeader.biWidth = width;
    bitmapInfo.bmiHeader.biHeight = height;
    bitmapInfo.bmiHeader.biPlanes = 1;
    bitmapInfo.bmiHeader.biBitCount = 32;
    bitmapInfo.bmiHeader.biCompression = BI_RGB;

    CBitmap bitmap;
    void* bits = 0;
    bitmap.Attach(CreateDIBSection(nullptr, &bitmapInfo, DIB_RGB_COLORS, &bits, nullptr, 0));

    // create a DC render target
    CComPtr<ID2D1DCRenderTarget> target;
    D2D1_RENDER_TARGET_PROPERTIES props = {};
    props.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
    props.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
    hr = factory->CreateDCRenderTarget(&props, &target);

    // create a DC, select bitmap and bind DC
    CDC cdc;
    cdc.CreateCompatibleDC(nullptr);
    auto old = cdc.SelectObject(bitmap);
    RECT rc = { 0, 0, width, height };
    hr = target->BindDC(cdc.GetSafeHdc(), &rc);

    // this requires Windows 10 1703
    CComPtr<ID2D1DeviceContext5> dc;
    hr = target->QueryInterface(&dc);

    // open a stream from the .SVG file
    CComPtr<IStream> svgStream;
    hr = SHCreateStreamOnFileW(L"c:\\mypath\\myfile.svg", 0, &svgStream);

    // open the SVG as a document
    CComPtr<ID2D1SvgDocument> svg;
    D2D1_SIZE_F size = { (float)width, (float)height };
    hr = dc->CreateSvgDocument(svgStream, size, &svg);

    // draw it on the render target
    target->BeginDraw();
    dc->DrawSvgDocument(svg);
    hr = target->EndDraw();

    // TODO
    // do something with the CBitmap
    // TODO

    // cleanup, etc.
    cdc.SelectObject(old);
}

int main()
{
    BuildSvgAsCBitmap(200, 200);
    return 0;
}

这里有一个更完整的示例https://gist.github.com/smourier/5b770d32043121d477a8079ef6be0995,它还演示了如何使用 WIC 将 svg 保存为具有透明度的 png。

© www.soinside.com 2019 - 2024. All rights reserved.