Closed iocoker closed 1 year ago
Thank you for reporting this.
In order to fix this issue, I would appreciate if you could provide a sample SVG (paired with the obtained render) showing the problem so I can reproduce it (I do not easily see it in the opacity tests that EchoSVG has).
You could provide a SVG file of your own, or something based on the files in samples/tests/spec/rendering
(the rendered PNGs are in test-references/samples/tests/spec/rendering
).
Thanks, here are the files.
opaque sample.pdf opacity sample.pdf
Sorry the SVGs have a transparent background, so the effect could be seen better in white theme.
It's actually a relic from Batik, so not unique to Echosvg, I'm just thinking perhaps there's a way to enable some flags or so to make it retain crisps vector even with opacity. A way out was to use fill-opacity but the same issue plaques images, as they are drawn to a Graphics2D
very poorly once they have any opacity or any filter.
Here's a reference to the same issue: https://github.com/rototor/pdfbox-graphics2d/issues/30#issuecomment-799236574
We're using the GraphicsNode.paint
method to draw the content unto a Graphics2D
canvas and that gets rendered into PDF. It retains the vector state until the opacity is set to anything less than 1.
Thank you
I tested drawGlyphVectorWorks = true
as suggested in the pdfbox thread, but the results are bad. For example the Font1
test produced the following Font1_cmp.png
comparison image (reference image is at left, drawGlyphVectorWorks = true
at right):
And the diff image Font1_diff.png
:
In case you want to experiment yourself, you can find these comparison images under echosvg-test/build/reports/tests/test/images
after running the tests with Gradle or Eclipse.
It should be possible to fix this issue (leveraging the fact that, unlike Batik, EchoSVG supports colors with an alpha channel), but it is not so easy as just changing a setting.
Thanks for checking this out; Indeed it's so much work tracing the issue. I'll give it a try.
Actually, I'm not sure that I reproduced the problem. I rendered the following SVG, which comes from your sample:
<svg width="243.78" height="153.07" xmlns="http://www.w3.org/2000/svg">
<g>
<text xml:space="preserve" font-family="Arial" font-size="40" font-weight="bold"
style="stroke:none;stroke-width:0;stroke-dasharray:none;stroke-linecap:butt;stroke-dashoffset:0;stroke-linejoin:miter;stroke-miterlimit:4;fill:#000;fill-rule:nonzero;opacity:.5;white-space:pre"
transform="matrix(.558 0 0 .558 121.83 76.484)"><tspan x="-116.338" y="12.566">Sample Test</tspan></text>
</g>
</svg>
and here is the resulting PNG:
which is what I'd expect. Perhaps you are overscaling the image?
I've created another (more complex) test where I checked putting the opacity in several different ways (inherited from another style, as an attribute in the text
and g
elements,...) and still do not see the issue.
In case I'm missing something, would appreciate more information.
Let's add that the sample image that you provide (in the "opacity sample" PDF) was apparently rendered without anti-aliasing, and in the normal EchoSVG rendering process, anti-aliasing is enabled (it is SVG's default) unless one disables it explicitly.
More information is clearly required.
@carlosame, thanks again for looking into this further.
So, here's a sample of our code: Basically we load an SVG string using echosvg, then get a graphicsNode and pass it a graphics2d canvas (we get that from pdfbox-graphics2d) and paint the graphics unto the g2d. Then from there it's encoded into a PDF via ApachePDFBox.
With opacity = 1, this is what the PDF comes to:
With opacity less than 1, this is what we get:
The first retains vector mode, the one with opacity just turns to raster image. I think it has to do with the compositing, as even it treats opacity the same way it does filters, which is, just turn it into bitmap.
We did try SVGSalamanda, just to be sure it's not pdfbox-graphics2d and came out fine with opacity. But SVGSalamanda isn't as mature or feature complete as echosvg, especially when it comes to fonts handling
So, it's not something that can be deduced outputting to a PNG, even if we did increase the resolution, it's still a raster and not that good for print.
I hope this sheds more light into the issue.
@iocoker would you mind checking the latest 0.3-SNAPSHOT
? It may fix this issue or at least be a mitigation.
Unfortunately I have no repository for snapshots, so the idea would be to run:
./gradlew build publishToMavenLocal
and then using the library from your Maven local repository.
This issue has been pending a response for more than two months. Lacking a reproducer, it is unclear whether it has been fixed or not, so I'm closing it.
If the problem described in this issue persists, please open a new one with a unit test that reproduces it.
HI there, thanks for this awesome work. This is a question.
Currently, we tried using echosvg to load SVG through the bridge and then paint it unto a Graphics2D context. However, if an item has opacity less than 1, the system automatically rasterizes it into a very low quality image. It happens for Text, Paths, Rect any svg element with an opacity gets painted as a raster image.
I assume it's treating the opacity as a filter effect, whereas it shouldn't be.
Is there a way to prevent this?