如何在C++ Win32 API中将矢量图像光栅化生成HBITMAP
实现矢量数据光栅化生成HBITMAP的方案
推荐方案:使用Win32原生GDI+实现(无需引入第三方依赖)
前置准备
- 项目配置中添加gdiplus.lib链接依赖,代码中引入头文件
#include <gdiplus.h> - 程序初始化阶段启动GDI+:
Gdiplus::GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
程序退出前调用Gdiplus::GdiplusShutdown(gdiplusToken)释放资源。
核心绘制流程
- 创建内存位图与绘图上下文
根据你VectorTexture中rect的宽高创建对应尺寸的GDI+位图,同时开启抗锯齿优化绘制效果:
int bitmapWidth = static_cast<int>(vectorTexture.rect.width); int bitmapHeight = static_cast<int>(vectorTexture.rect.height); Gdiplus::Bitmap bitmap(bitmapWidth, bitmapHeight, PixelFormat32bppARGB); Gdiplus::Graphics graphics(&bitmap); // 开启抗锯齿 graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); // 可选:填充背景色 graphics.Clear(Gdiplus::Color(255, 255, 255));
- 遍历形状列表逐个绘制
根据每个Shape的类型调用对应GDI+绘制接口,示例代码如下(默认使用1像素黑色描边、白色填充,你可根据SVG解析得到的样式属性调整画笔、画刷参数):
Gdiplus::Pen blackPen(Gdiplus::Color(255, 0, 0, 0), 1.0f); Gdiplus::Brush whiteBrush(Gdiplus::Color(255, 255, 255, 255)); for (const auto& shape : vectorTexture.shapes) { switch (shape.type) { case VectorTexture::Circle: { float x = shape.data[0], y = shape.data[1], r = shape.data[2]; graphics.DrawEllipse(&blackPen, x - r, y - r, 2 * r, 2 * r); graphics.FillEllipse(&whiteBrush, x - r, y - r, 2 * r, 2 * r); break; } case VectorTexture::Line: { float x1 = shape.data[0], y1 = shape.data[1]; float x2 = shape.data[2], y2 = shape.data[3]; float lineWidth = shape.data[4]; blackPen.SetWidth(lineWidth); graphics.DrawLine(&blackPen, x1, y1, x2, y2); break; } case VectorTexture::Rectangle: { float x = shape.data[0], y = shape.data[1]; float w = shape.data[2], h = shape.data[3]; graphics.DrawRectangle(&blackPen, x, y, w, h); graphics.FillRectangle(&whiteBrush, x, y, w, h); break; } case VectorTexture::Square: { float x = shape.data[0], y = shape.data[1], a = shape.data[2]; graphics.DrawRectangle(&blackPen, x, y, a, a); graphics.FillRectangle(&whiteBrush, x, y, a, a); break; } case VectorTexture::Polygon: { // 按你实际存储的多边形顶点数替换pointCount取值逻辑 int pointCount = 0; std::vector<Gdiplus::PointF> points(pointCount); for (int i = 0; i < pointCount; i++) { points[i].X = shape.data[2 * i]; points[i].Y = shape.data[2 * i + 1]; } graphics.DrawPolygon(&blackPen, points.data(), pointCount); graphics.FillPolygon(&whiteBrush, points.data(), pointCount); break; } } }
- 转换为HBITMAP
绘制完成后直接调用GDI+ Bitmap的接口即可得到可用的HBITMAP:
HBITMAP hBitmap; bitmap.GetHBITMAP(Gdiplus::Color(255, 255, 255), &hBitmap);
拿到的hBitmap可直接通过BitBlt、StretchBlt等Win32 API绘制到窗口DC上展示,使用完成后需要调用DeleteObject(hBitmap)释放资源,避免内存泄漏。
可选方案:手动实现光栅化
如果你希望深入学习光栅化原理,可以手动创建DIB段拿到像素缓冲区指针,自行实现各形状的扫描线绘制、抗锯齿、颜色混合逻辑,DIB段本身可直接作为HBITMAP使用。该方案需要处理的边界逻辑较多,包括多边形填充规则、线段抗锯齿算法、坐标变换等,适合学习用途,生产环境更推荐使用上述GDI+方案。
内容的提问来源于stack exchange,提问作者Hitarth Padaliya
相关产品推荐
相关产品推荐

