Closed astotrzynascie closed 6 months ago
resvg produces an image with a premultiplied alpha. Do you account for that in your code?
PS: I'm not sure why it has anything to do with Qt::transparent
. You don't need Qt to use this library.
Oh, I noticed:
* @param pixmap Pixmap data. Should have width*height*4 size and contain
* premultiplied RGBA8888 pixels.
but somehow, I didn't think of the result being premultiplied...
Changed
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
to
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
and it looks good (funny, I could swear I tested other blend modes). Sorry for bothering, thanks a lot!
No problems.
Hello.
I'm using resvg as a C library. I need to generate textures (from svg files). Can't generate it directly in GPU (resvg doesn't support it). Providing background is also not an option, because background is dynamic, in GPU memory, and I would have to copy it back-and-forth each frame. So, I figured out that I need a texture that is generated on fully 'transparent' background and will fit to any other.
From what I've seen, in Qt example filling surface goes this way:
As I'm not using Qt, checked that Qt::transparent is just black with alpha set to 0. So I started with filling the surface with zeroes:
But I noticed, that on white background antialiased edges looks like antialiased against black background.
My experiment with changing the surface made me sure that during some processing there is an ordinary average involved. For example, I changed the red component:
...and the edges near background turned red.
So it looks like the fact that alpha is zero is ignored. When processing pixels all components seem to be taken under consideration, so when new value for red component is being calculated, alpha is ignored, ordinary average is being used and the edges gets redish.
Given the surface, it is impossible to declare it fully transparent. It leads to conclusion that rasterization this way will always process 'color of background' and ignore the fact that alpha is zero. And with all zeroes, edges get darker.
Workaround: Generate image 4x bigger, with
(which gives no antialiased edges) and then manually shrink the image but using weighted sums, with alpha values as weights.
Edges are not contaminated with any 'background color', they contain just original components with appropriate alpha, and the texture looks good blended with any background.
Anyway, I'd like to see some fix to resvg which will make such a workaround unnecessary. And, as I don't use Qt, I'm curious if 'Qt::transparent' also makes antialiased edges darker (instead of preserving the color). It should (or bytes in surface are somehow magically marked to be really transparent and algorithm handles it).