QSvgRenderer rendering on QImage leads to transparent color bleeding into result image
-
When rendering .svg image with QSvgRenderer into QImage, filled with transparent 'color' (alpha channel 0), resulting image has color bleeding on edges.
Whenever I use Qt::transparent, its black. If I use any qRgba(r,g,b,0), that color will also bleed (e.g. white).
Is there any way to fix that?Screenshot with a problem:
Here you can notice a dark border around two left shapes (dark border around circle, dark border around triangle), and you might notice (yet its almost invisible) a white border around right ones. It is better visible in image editing tools (like Paint).
Qt 5.15.5, on Windows
Code is simple as that:QImage image(width, height, QImage::Format_ARGB32_Premultiplied); image.fill(Qt::transparent); ... other things ... QSvgRenderer renderer; ... read svg ... QPainter painter(&image); renderer.render(&painter);
-
This looks like a filtering issue, you gotta look into premultiplying the alpha before resampling.
Basically pixels with alpha end up making an (incorrect) contribution to the final pixel color when combining multiple source pixels into a single pixel during resampling.
https://shawnhargreaves.com/blog/texture-filtering-alpha-cutouts.html
I'm using SvgViewWidget from Qt samples and it's using
QImage::Format_ARGB32_Premultiplied
as the image format.
https://doc.qt.io/qt-5/qtsvg-svgviewer-example.html
EDIT: Sorry I somehow just noticed that your code is also using ARGB32_Premultiplied as the QImageFormat so nm.
-
Also as I found out, that resulting image is not directly painted. QImage is transformed in uchar array by it's methods, then transferred in another function, and then QImage is reconstructed from that uchar array and this image is painted by QPainter. Might it be the issue?
-
@hexaden said in QSvgRenderer rendering on QImage leads to transparent color bleeding into result image:
Might it be the issue
A QImage is not more than a bunch of bytes... So there is no 'conversion' from QImage to uchar and back.
-
@Christian-Ehrlicher so, you mean that such conversion is invalid?
QImage img(w, h, format); *fill image* auto bits = new uchar[img.sizeInBytes()]; memcpy(bits, img.bits(), img.sizeInBytes()); QImage restored(bits, w, h, format);
-
@hexaden said in QSvgRenderer rendering on QImage leads to transparent color bleeding into result image:
and I asked if that might cause problems
No, unless the buffered data is changed before second image is created from this buffer. You also have to be careful: "The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer.", see https://doc.qt.io/qt-6/qimage.html#QImage-3
-
@jsulm restored QImage is very local, and buffer lives in outer scope for much longer time. I will double check if that buffer is ever modified, but I'm pretty sure it is not ever touched for writing (there is no public interface for it to be changed).
-
@JoeCFD it's of different color but it doesn't matter.
<?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 51 51" enable-background="new 0 0 51 51" xml:space="preserve"> <path id="SymbolPreviewStroke" fill="#24D900" transform="rotate(0,26,26)" d="M25.5,13.6L19,32h13L25.5,13.6z M25.5,18.1l4.4,12.4h-8.8L25.5,18.1z"/> </svg>
-
It is a green triangle. I replaced one of my icons with yours and can not see any border.
Ubuntu 22.04 and Qt 5.15.3QFile file(filename); file.open( QIODevice::ReadOnly ); QString str( QString::fromUtf8( file.readAll() ) ); QSvgRenderer svgRenderer( str.toUtf8() ); QPixmap * pixmap = new QPixmap( QSize( image_width, image_height ) ); pixmap->fill( Qt::transparent ); QPainter pixPainter( pixmap ); svgRenderer.render(&pixPainter);
-
So, I just tested things, turns out the problem is indeed in QImage reconstruction (at least I think so). QPixmap/QImage is painted just fine, without any issues, before deconstruction into array, and it is painted with color bleeding after reconstruction (in non-isolated example, with all program code inbetween).
-