1

I have this SVG file:

<svg version="1.1" viewBox="0 0 390 390" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <line class="arrow" opacity="0.5" stroke="#15781B" stroke-linecap="butt" stroke-width="9.0" x1="307.5" x2="279.60592002787337" y1="352.5" y2="296.7118400557468" />
    <polygon class="arrow" fill="#15781B" opacity="0.5019607843137255" points="264.51246117974983,266.5249223594996 264.5124611797498,304.25856947980856 294.69937887599696,289.165110631685" />
    <text fill="white" font-size="11" font-weight="bold" opacity="0.5" x="264.0" y="291.0">DEF</text>
    <line class="arrow" opacity="0.5019607843137255" stroke="#15781B" stroke-linecap="butt" stroke-width="9.0" x1="262.5" x2="262.5" y1="307.5" y2="255.75" />
    <polygon class="arrow" fill="#15781B" opacity="0.5" points="262.5,222.0 245.625,255.75 279.375,255.75" />
    <text fill="white"  font-size="11" font-weight="bold" opacity="0.5" x="252.0" y="249.0">ABC</text>
</svg>

If you save it as a b.svg file, and open it, you will see that there is some overlapping with opacity : the text ABC and DEF is readable.

Now when I render it in a PDF file with the well-known method from Generating PDFs from SVG input :

from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF
drawing = svg2rlg("b.svg")
renderPDF.drawToFile(drawing, "b.pdf")

then the opacity is lost in the PDF file, and the left part of the D letter of "DEF" is unreadable:

enter image description here

Question: How to include a SVG into a PDF and keep the opacity?

Basj
  • 41,386
  • 99
  • 383
  • 673

2 Answers2

3

A quick look at the svglib code shows that svglib does not parse the "opacity" attribute, but it does parse the "fill-opacity" and "stroke-opacity" attributes. So changing your svg to

<svg version="1.1" viewBox="0 0 390 390" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <line class="arrow" fill-opacity="0.5" stroke-opacity="0.5" stroke="#15781B" stroke-linecap="butt" stroke-width="9.0" x1="307.5" x2="279.60592002787337" y1="352.5" y2="296.7118400557468" />
    <polygon class="arrow" fill="#15781B" fill-opacity="0.5019607843137255" stroke-opacity="0.5019607843137255" points="264.51246117974983,266.5249223594996 264.5124611797498,304.25856947980856 294.69937887599696,289.165110631685" />
    <text fill="white" font-size="11" font-weight="bold" fill-opacity="0.5" stroke-opacity="0.5" x="264.0" y="291.0">DEF</text>
    <line class="arrow" fill-opacity="0.5019607843137255" stroke-opacity="0.5019607843137255" stroke="#15781B" stroke-linecap="butt" stroke-width="9.0" x1="262.5" x2="262.5" y1="307.5" y2="255.75" />
    <polygon class="arrow" fill="#15781B" fill-opacity="0.5" stroke-opacity="0.5" points="262.5,222.0 245.625,255.75 279.375,255.75" />
    <text fill="white"  font-size="11" font-weight="bold" fill-opacity="0.5" stroke-opacity="0.5" x="252.0" y="249.0">ABC</text>
</svg>

should do the trick. enter image description here

UPDATE

This seems to be an open issue since 2018

zap
  • 568
  • 2
  • 13
0

To long for a comment and the Kudos / Bonus should go to @zap for pointing me at rebuilding all the shapes to Polygons which worked significantly better than Rect.

I still struggle to understand twice so as to get WkHtmlToPDF to give me a good scalar PDF but it did give me transparency with the following.

<svg version="1.1" viewBox="0 0 390 390" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <polygon class="arrow" fill="#15781B" fill-opacity="0.5" stroke-opacity="0.5" points="275.75,298.6 283.6,294.6 312,350.5 303.5,354.5" />
    <polygon class="arrow" fill="#15781B" fill-opacity="0.5" stroke-opacity="0.5" points="264.5125,266.5249 264.5125,304.25856 294.6994,289.1651" />
    <text fill="white" font-size="11" font-weight="bold" fill-opacity="0.5" stroke-opacity="0.5" x="264.0" y="291.0">DEF</text>
    <polygon class="arrow" fill="#15781B" fill-opacity="0.5" stroke-opacity="0.5" points="258,255.75 267,255.75 267,307.5 258,307.5" />
    <polygon class="arrow" fill="#15781B" fill-opacity="0.5" stroke-opacity="0.5" points="262.5,222.0 245.625,255.75 279.375,255.75" />
    <text fill="white"  font-size="11" font-weight="bold" fill-opacity="0.5" stroke-opacity="0.5" x="250" y="250.0">ABC</text>
</svg>

Here are the transparent objects on a transparent background on a snowy day. Somewhere there must be a means to fix scaling but I did not find it yet and others have said similar. enter image description here

The Idea was to keep a minimal as possible approach without any special external adjustments (though I did try many). So the SVG was included as img in an HTML "square" block.

"test1.htm"

<!DOCTYPE html>
<html>
  <head>
  <style>
    body {background: transparent;}
  </style>
  </head>
  <body>
    <img src="file:///wkhtmltox\bin\test1.svg" height=390px width=780px />
  </body>
</html>

and called directly

wkhtmltopdf.exe --enable-local-file-access  --disable-smart-shrinking --no-background --no-pdf-compression -n "test1.htm" test1.pdf

In the spirit of maintaining opacity I included that aspect in the body style and external --no-background but they normally would not be required And finally I seem to have got scaling stable so here is the SVG in an A4 transparent page. enter image description here

K J
  • 8,045
  • 3
  • 14
  • 36
  • Thank you. Can you include some code to show how your converted SVG to PDF with WkHtmlToPDF? There are other posts about this but some sample code would still be helpful, some details (about opacity, etc.) might be important here. – Basj Jun 25 '21 at 06:45