使用 NanoSVG 颜色问题将 SVG 转换为 HBITMAP

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

我尝试使用 NanoSVG 将 SVG 转换为 HBITMAP。一切正常,但 Bitamp 或保存的 png 的颜色与原始 svg 不同。请帮我解决这个问题

我试过下面的代码

// Load the SVG file
NSVGimage* image = nsvgParseFromFile(filename, "px", 96);

// Create a bitmap with the same dimensions as the SVG image
BITMAPINFO bmpinfo = { 0 };
bmpinfo.bmiHeader.biSize = sizeof(bmpinfo.bmiHeader);
bmpinfo.bmiHeader.biWidth = static_cast<LONG>(image->width);
bmpinfo.bmiHeader.biHeight = -static_cast<LONG>(image->height);
bmpinfo.bmiHeader.biPlanes = 1;
bmpinfo.bmiHeader.biBitCount = 32;
bmpinfo.bmiHeader.biCompression = BI_RGB;

void* bits = nullptr;   
HBITMAP hbitmap = CreateDIBSection(NULL, &bmpinfo, DIB_RGB_COLORS, &bits, nullptr, 0);

// Render the SVG image to the bitmap
NSVGrasterizer* rast = nsvgCreateRasterizer();

nsvgRasterize(rast, image, 0, 0, 1, (unsigned char*)bits, static_cast<int>(image->width), static_cast<int>(image->height), static_cast<int>(image->width * 4));
nsvgDeleteRasterizer(rast);

// Clean up
nsvgDelete(image);
c++ mfc hbitmap
1个回答
0
投票

问题是红色通道和蓝色通道被交换了,因为 CreateDIBSection 期望 BGR 有序颜色,而 NanoSVG 正在输出 RGB。 CreateDIBSection 的文档在这一点上不太清楚,但如果您查看 the definition of RGBQUAD 的文档,您可以看到它的布局为蓝-绿-红。

无论如何,我没有看到一种方法来控制 NanoSVG 中的字节顺序,所以直接的选择是手动交换字节。如下所示...(我还修复了您的代码中的一个小问题,在该问题中,由于从浮点宽度到整数宽度的转换,只需在浮动尺寸并在任何地方使用它。)

void rgb_to_bgr(unsigned char* bits, int n) {
    for (int i = 0; i < n; i += 4) {
        std::swap(bits[i], bits[i + 2]);
    }
}

HBITMAP paint_svg(const char* filename) {
    // Load the SVG file
    NSVGimage* image = nsvgParseFromFile(filename, "px", 96);

    int wd = static_cast<int>(std::ceil(image->width));
    int hgt = static_cast<int>(std::ceil(image->height));
    int stride = wd * 4;

    // Create a bitmap with the same dimensions as the SVG image
    BITMAPINFO bmpinfo = { 0 };
    bmpinfo.bmiHeader.biSize = sizeof(bmpinfo.bmiHeader);
    bmpinfo.bmiHeader.biWidth = wd;
    bmpinfo.bmiHeader.biHeight = -hgt;
    bmpinfo.bmiHeader.biPlanes = 1;
    bmpinfo.bmiHeader.biBitCount = 32;
    bmpinfo.bmiHeader.biCompression = BI_RGB;

    unsigned char* bits = nullptr;
    HBITMAP hbitmap = CreateDIBSection(NULL, &bmpinfo, DIB_RGB_COLORS, 
        reinterpret_cast<void**>(&bits), nullptr, 0);

    // Render the SVG image to the bitmap
    NSVGrasterizer* rast = nsvgCreateRasterizer();

    nsvgRasterize(rast, image, 0, 0, 1, bits, wd, hgt, stride);
    rgb_to_bgr(bits, hgt * stride);

    nsvgDeleteRasterizer(rast);

    // Clean up
    nsvgDelete(image);
    return hbitmap
}
© www.soinside.com 2019 - 2024. All rights reserved.