Export clean SVG icons from IconVectors and render them in C++ using frameworks like WinUI/Win2D (Windows) or Qt (cross‑platform). This guide shows practical snippets, theming options, and packaging tips.
When to choose C++ code
- You’re building native desktop apps (Windows, Linux, macOS) and want resolution‑independent vector icons.
- You already use frameworks that can draw SVGs at runtime (Win2D/Direct2D on Windows, Qt’s
QSvgRenderer
on all major platforms). - You need predictable sizing via a consistent
viewBox
(e.g.,0 0 24 24
) and easy recoloring strategies.
Draw, Import or Trace your icon
- Start by drawing directly in IconVectors. Use the shape, pen, and path tools to build icons on a pixel-perfect grid (16/20/24/32 px). Align strokes to whole pixels for maximum sharpness at small sizes.
- File → Place lets you import an existing SVG file into your current document—useful for reusing assets from Figma, Illustrator, or Inkscape.
- File → Place and Trace Bitmap inserts a bitmap (PNG/JPG/BMP) and converts it to vector paths, optimized for monochrome sources like glyphs or sketches.
- You can also Copy/Paste vector content from external tools; IconVectors interprets the SVG data in the clipboard and adds it to the canvas.
- Or draw from scratch with rectangles, ellipses, lines, pen, path editing, and boolean operations for full control.

Export an SVG for C++ integration
- Design on a consistent grid (e.g., 24×24). Keep strokes aligned to whole pixels.
- Set theming strategy: for single‑color icons, prefer
currentColor
onfill
orstroke
so CSS can control color. - Open the Live Code Viewer (F3) and switch to the C++ tab.
- Copy the generated component and save it to your project.
wxWidgets — rasterize SVG with lunaSVG and draw as wxBitmap
This example parses an SVG from an in‑memory std::string
using lunaSVG, rasterizes it to an RGBA bitmap,
converts that bitmap into a wxBitmap
, and draws it in a standard wxWidgets window.
(You can also persist the raster result to PNG if you need files.)
#include <wx/wx.h>
#include <lunasvg.h>
using namespace lunasvg;
// 1) Your SVG as a raw string (exact sample you provided)
static const std::string kSvg = R"SVG(
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"
d="M2.5 9C2.5 2.4 10 3 12.1 7.5C14.1 3 21.6 2.5 21.6 9C21.6 15.5 12.1 21.6 12.1 21.6C12.1 21.6 2.5 15.6 2.5 9z"/>
</svg>
)SVG";
// 2) Convert lunaSVG::Bitmap (RGBA) -> wxBitmap with alpha
static wxBitmap WxBitmapFromLuna(const Bitmap& bmp)
{
const int w = bmp.width();
const int h = bmp.height();
const unsigned char* rgba = bmp.data(); // RGBA (4 bytes per pixel)
// wxImage expects separate RGB and Alpha buffers (it takes ownership)
auto* rgb = new unsigned char[w * h * 3];
auto* alpha = new unsigned char[w * h];
for (int i = 0, rp = 0, ap = 0; i < w * h; ++i)
{
rgb[rp++] = rgba[4 * i + 0]; // R
rgb[rp++] = rgba[4 * i + 1]; // G
rgb[rp++] = rgba[4 * i + 2]; // B
alpha[ap++] = rgba[4 * i + 3]; // A
}
wxImage img(w, h);
img.SetData(rgb); // transfers ownership
img.SetAlpha(alpha); // transfers ownership
return wxBitmap(img, 32); // 32-bit with alpha
}
// 3) Minimal wxWidgets app that renders the SVG via lunaSVG, then draws it
class MyFrame : public wxFrame
{
public:
MyFrame(wxBitmap bmp)
: wxFrame(nullptr, wxID_ANY, "wxWidgets + lunaSVG", wxDefaultPosition, wxSize(220, 220))
, m_bmp(std::move(bmp))
{
Bind(wxEVT_PAINT, &MyFrame::OnPaint, this);
}
private:
void OnPaint(wxPaintEvent&)
{
wxPaintDC dc(this);
// Draw with transparency; adjust position as needed
dc.DrawBitmap(m_bmp, 16, 16, /* useMask */ true);
}
wxBitmap m_bmp;
};
class MyApp : public wxApp
{
public:
bool OnInit() override
{
// Parse SVG from memory
auto doc = Document::loadFromData(kSvg);
if (!doc) return false;
// Rasterize to RGBA bitmap; pass target size if desired (e.g., 24x24)
Bitmap lunaBmp = doc->renderToBitmap(24, 24); // scales and preserves crispness
if (lunaBmp.isNull()) return false;
// Optional: also save to PNG on disk
// lunaBmp.writeToPng("output.png");
// Convert to wxBitmap (with alpha) and show in a frame
wxBitmap wxbmp = WxBitmapFromLuna(lunaBmp);
(new MyFrame(std::move(wxbmp)))->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
Build note: link your app with wxWidgets
and lunaSVG
(e.g., CMake: find_package(wxWidgets ...)
,
target_link_libraries(app PRIVATE ${wxWidgets_LIBRARIES} lunasvg)
). On Windows, ensure UTF‑8 source and a recent wxWidgets (3.1+/3.2+) for alpha drawing.
Windows (WinUI/Win2D) — draw an SVG
Win2D’s CanvasSvgDocument
renders SVG directly in C++/WinRT or C++/CX apps.
// C++/WinRT example (WinUI/UWP) — load and draw an SVG
#include <winrt/Microsoft.Graphics.Canvas.h>
#include <winrt/Microsoft.Graphics.Canvas.Svg.h>
using namespace winrt;
using namespace Microsoft::Graphics::Canvas;
using namespace Microsoft::Graphics::Canvas::Svg;
CanvasDevice device = CanvasDevice();
auto file = co_await Windows::Storage::StorageFile::GetFileFromApplicationUriAsync(
Windows::Foundation::Uri(L"ms-appx:///Assets/icons/heart_24.svg"));
auto stream = co_await file.OpenReadAsync();
CanvasSvgDocument svgDoc = co_await CanvasSvgDocument::LoadAsync(device, stream);
// inside your Draw handler
void Draw(CanvasDrawingSession const& ds, Windows::Foundation::Rect dst) {
ds.DrawSvg(svgDoc, dst); // scales crisply to the destination rect
}
Qt (cross‑platform) — render with QSvgRenderer
Qt’s QSvgRenderer
draws SVGs onto any QPainter
target (widgets, pixmaps, images).
#include <QSvgRenderer>
#include <QPainter>
#include <QPixmap>
QPixmap makeIconPixmap(const QString& path, int size) {
QSvgRenderer renderer(path);
QPixmap pm(size, size);
pm.fill(Qt::transparent);
QPainter p(&pm);
renderer.render(&p, QRectF(0, 0, size, size));
return pm;
}
// usage: set on QLabel, QAction/QIcon, etc.
auto pm = makeIconPixmap(":/icons/heart_24.svg", 24);
Recoloring strategies
- At export: export a monochrome icon in your desired color.
- At runtime (Qt): read the SVG as text and replace
fill="currentColor"
(or a placeholder) with a theme color, then give aQByteArray
toQSvgRenderer
. - At runtime (Win2D): draw into a temporary surface and tint via composition/blend if you need dynamic color without editing the SVG.
// Qt: replace color token at runtime, then render
QByteArray svg = loadFileBytes(":/icons/heart_24.svg");
svg.replace("currentColor", "#2563EB"); // example theme color
QSvgRenderer renderer(svg);
QPixmap pm(24, 24); pm.fill(Qt::transparent);
QPainter p(&pm); renderer.render(&p, QRectF(0,0,24,24));
Packaging icons
- Embed as resources:
WinUI — put SVGs in
Assets/
and load viams-appx:///
; Qt — add to a.qrc
file and reference via:/
paths. - Consistent naming:
icons/24/heart.svg
,icons/16/heart.svg
for clarity across sizes. - Fallback PNGs: if you must support environments without runtime SVG, batch‑export PNGs (1×/2×/3×) from IconVectors and load them conditionally.
Accessibility notes
- Icons alone don’t carry semantics. Pair with text or set accessible names on the host control (e.g., WinUI’s
AutomationProperties.Name
). - For purely decorative icons, mark them as such on the control so screen readers ignore them.
Performance tips
- Prefer simple paths; avoid heavy filters in SVG (they’re slower and larger).
- Render once to a bitmap/cache if the same icon is drawn repeatedly at the same size.
- Stick to a standard viewBox (e.g., 24×24) for predictable scaling across the set.
Reference example (SVG path)
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="M2.5 9C2.5 2.5 10 3 12 7.5C14 3 21.5 2.5 21.5 9C21.5 15.4 12 21.5 12 21.5C12 21.5 2.5 15.6 2.5 9z"/>
</svg>