我尝试使用 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);
问题是红色通道和蓝色通道被交换了,因为 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
}