使用 Reportlab 将 SVG 保存为 PDF 时出现不透明度问题
Opacity issue when saving a SVG in a PDF with Reportlab
我有这个 SVG 文件:
<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>
如果将其另存为 b.svg
文件,然后打开它,您会看到有一些不透明度重叠:文本 ABC
和 DEF
可读.
现在,当我使用 Generating PDFs from SVG input 中众所周知的方法将其呈现在 PDF 文件中时:
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF
drawing = svg2rlg("b.svg")
renderPDF.drawToFile(drawing, "b.pdf")
然后PDF文件中不透明度丢失,“DEF”的D字母左边部分不可读:
问题:如何将 SVG 包含到 PDF 中并保持不透明度?
快速查看 svglib 代码表明 svglib 不解析“opacity”属性,但它解析“fill-opacity”和“stroke-opacity”属性。因此,将您的 svg 更改为
<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>
应该可以解决问题。
更新
这似乎是 open issue 自 2018 年以来
期待评论和荣誉/奖金应该给@zap,因为他指出我将所有形状重建为多边形,其效果明显优于矩形。
我还在努力理解了两遍,以便让WkHtmlToPDF给我一个好的scalar PDF 但它确实给了我以下内容的透明度。
<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>
这是雪天透明背景上的透明物体。
某处必须有一种方法来修复缩放,但我还没有找到它,其他人也说过类似的话。
我的想法是在不进行任何特殊外部调整的情况下保持尽可能少的方法(尽管我确实尝试了很多)。因此 SVG 作为 img 包含在 HTML“方形”块中。
"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>
并直接调用
wkhtmltopdf.exe --enable-local-file-access --disable-smart-shrinking --no-background --no-pdf-compression -n "test1.htm" test1.pdf
本着保持不透明度的精神,我在主体样式和外部 --no-background 中包括了这一方面,但通常不需要它们
最后我似乎已经稳定缩放,所以这里是 A4 透明页面中的 SVG。
我有这个 SVG 文件:
<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>
如果将其另存为 b.svg
文件,然后打开它,您会看到有一些不透明度重叠:文本 ABC
和 DEF
可读.
现在,当我使用 Generating PDFs from SVG input 中众所周知的方法将其呈现在 PDF 文件中时:
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF
drawing = svg2rlg("b.svg")
renderPDF.drawToFile(drawing, "b.pdf")
然后PDF文件中不透明度丢失,“DEF”的D字母左边部分不可读:
问题:如何将 SVG 包含到 PDF 中并保持不透明度?
快速查看 svglib 代码表明 svglib 不解析“opacity”属性,但它解析“fill-opacity”和“stroke-opacity”属性。因此,将您的 svg 更改为
<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>
应该可以解决问题。
更新
这似乎是 open issue 自 2018 年以来
期待评论和荣誉/奖金应该给@zap,因为他指出我将所有形状重建为多边形,其效果明显优于矩形。
我还在努力理解了两遍,以便让WkHtmlToPDF给我一个好的scalar PDF 但它确实给了我以下内容的透明度。
<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>
这是雪天透明背景上的透明物体。
某处必须有一种方法来修复缩放,但我还没有找到它,其他人也说过类似的话。
我的想法是在不进行任何特殊外部调整的情况下保持尽可能少的方法(尽管我确实尝试了很多)。因此 SVG 作为 img 包含在 HTML“方形”块中。
"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>
并直接调用
wkhtmltopdf.exe --enable-local-file-access --disable-smart-shrinking --no-background --no-pdf-compression -n "test1.htm" test1.pdf
本着保持不透明度的精神,我在主体样式和外部 --no-background 中包括了这一方面,但通常不需要它们
最后我似乎已经稳定缩放,所以这里是 A4 透明页面中的 SVG。