1 Attachment(s)
Create Transparent PNG Image
I want to convert SVG to PNG without background (transparent)
I use QtWebKit to acquire this
But it's not work, are you give me some idea to fix it ?
svg2png.h
Code:
#ifndef WEBKIT_SVG_RENDERER
#define WEBKIT_SVG_RENDERER
#include <QWebView>
class WebKitSVGRenderer : public QWebView
{
Q_OBJECT
public:
WebKitSVGRenderer
(QWidget *parent
= 0);
private slots:
void saveResult(bool ok);
};
#endif // WEBKIT_SVG_RENDERER
svg2png.cpp
Code:
#include "svg2png.h"
#include <iostream>
#include <QtGui>
#include <QtWebKit>
// large enough to enclose the SVG icons
#define MAGIC_SIZE 4095
WebKitSVGRenderer
::WebKitSVGRenderer(QWidget *parent
) : QWebView
(parent
){
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(saveResult(bool)));
setFixedSize(MAGIC_SIZE, MAGIC_SIZE);
pal.
setColor(QPalette::Background, Qt
::transparent);
setPalette(pal);
}
#define EVAL_JS(x) page()->mainFrame()->evaluateJavaScript((x))
void WebKitSVGRenderer::saveResult(bool ok)
{
// crude error-checking
if (!ok) {
std::cerr << "Failed loading " << qPrintable(url().toString()) << std::endl;
return;
}
// ensure it is an SVG
QString root
= EVAL_JS
("document.rootElement.nodeName").
toString();
if (root.isEmpty() || root.compare("svg", Qt::CaseInsensitive)) {
std::cerr << "Not an SVG! " << qPrintable(url().toString()) << std::endl;
close();
return;
}
// get the dimension, i.e. the width and height attributes
// Note: if an attribute is not defined WebKit would return the view's dimension
// hence the hack of checking for the MAGIC_SIZE
double ww = EVAL_JS("document.rootElement.width.baseVal.value").toDouble();
double hh = EVAL_JS("document.rootElement.height.baseVal.value").toDouble();
if (ww == 0.0 || hh == 0.0 || ww == MAGIC_SIZE || hh == MAGIC_SIZE) {
std::cerr << "SVG does not specify proper width and height! " << std::endl;
close();
return;
}
// try to give the best output file
if (fileName.isEmpty()) {
fileName
= QFileInfo(url
().
path()).
completeBaseName();
if (fileName.isEmpty())
fileName = "result";
fileName += ".png";
}
// create the target surface
QSize t
= targetSize.
isValid() ? targetSize
: QSize(ww, hh
);
img.fill(Qt::transparent);
// prepare the painter
qreal xs = targetSize.isValid() ? targetSize.width() / ww : 1.0;
qreal ys = targetSize.isValid() ? targetSize.height() / hh : 1.0;
p.scale(xs, ys);
// the best quality
p.
setRenderHint(QPainter::Antialiasing);
p.
setRenderHint(QPainter::TextAntialiasing);
p.
setRenderHint(QPainter::SmoothPixmapTransform);
page()->mainFrame()->render(&p);
p.end();
if (img.save(fileName, "png"))
std::cout << "Result saved to " << qPrintable(fileName) << std::endl;
else
std::cout << "Failed to save to " << qPrintable(fileName) << std::endl;
close();
}
static void usage()
{
std::cout << "Rasterize an SVG icon to a PNG image" << std::endl << std::endl;
std::cout << " svg2png input.svg [output.png [width height]]" << std::endl << std::endl;
std::cout << "Examples: " << std::endl;
std::cout << " svg2png tiger.svg" << std::endl;
std::cout << " svg2png icon.svg icon.png 256 256" << std::endl;
std::cout << std::endl;
}
int main(int argc, char * argv[])
{
if ((argc < 2) || (argc == 4)) {
usage();
return 0;
}
WebKitSVGRenderer renderer;
if (argc < 3)
renderer.
fileName = QString::fromLatin1(argv
[2]);
if (argc == 5) {
int w
= QString::fromLatin1(argv
[3]).
toInt();
int h
= QString::fromLatin1(argv
[4]).
toInt();
renderer.
targetSize = QSize(w, h
);
if (!renderer.targetSize.isValid() || w <= 0 || h <= 0) {
std::cerr << "Please specify a valid target size !" << std::endl;
return 0;
}
}
renderer.
load(QUrl::fromLocalFile(str
));
return a.exec();
}
Re: Create Transparent PNG Image
Have you tried QSvgRenderer? Currently if you render the frame, it probably contains its own background (the webpage is not transparent) which is also rendererd onto the device.