Friday, April 19, 2013

Qt: Save QPainter Output in an SVG or Image File

To save what you paint in a Qt window to a file (SVG or image) is an easy and straightforward piece of code.

You create a QSvgGenerator or a QImage object.
Some initialization.
Paint into the object (treat it as an IODevice)
And  we are done.

Suppose that this is what I draw in my paint event:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter;
    painter.begin(this);
    
    painter.setRenderHint(QPainter::Antialiasing);
    paint(painter);
    
    painter.end();
}

void MainWindow::paint(QPainter &painter)
{
    painter.setClipRect(QRect(0, 0, 200, 200));
    painter.setPen(Qt::NoPen);
    painter.fillRect(QRect(0, 0, 200, 200), Qt::gray);
    painter.setPen(QPen(Qt::white, 4, Qt::DashLine));
    painter.drawLine(QLine(0, 35, 200, 35));
    painter.drawLine(QLine(0, 165, 200, 165));
}


If I want to save it into an SVG file, it would be something like this

void MainWindow::saveSvg()
{
    QString path = QFileDialog::getSaveFileName(this, tr("Save as SVG"),"", tr("SVG file (*.svg)"));

    if (path.isEmpty())
        return;

    QSvgGenerator generator;
    generator.setFileName(path);
    generator.setSize(QSize(200, 200));
    generator.setViewBox(QRect(0, 0, 200, 200));
    generator.setTitle(tr("SVG Generator Example Drawing"));
    generator.setDescription(tr("An SVG drawing created by the SVG Generator "
                             "Example provided with Qt."));
    QPainter painter;
    painter.begin(&generator);
    paint(painter);
    painter.end();
}


If I want to save it into an image file, it would be something like this.

void MainWindow::savePng()
{
    QString path = QFileDialog::getSaveFileName(this, tr("Save as image"), "", tr("PNG file (*.png)"));

    if (path.isEmpty())
        return;

    QImage img(200, 200, QImage::Format_ARGB32);

    QPainter painter;
    painter.begin(&img);
    paint(painter);
    painter.end();

    img.save(path);
}

Note that if you  replace
QImage img(200, 200, QImage::Format_ARGB32);

QPainter painter;
painter.begin(&img);
paint(painter);
painter.end();
with
QImage img(this->size(), QImage::Format_ARGB32);
QPainter painter(&img);
this->render(&painter);
you'll be taking a screenshot of widget content into an image.


References:
SVG Generator Example
Capture Qt widget as an image file

1 comment: