如何用CairoSVG将含嵌入图片的SVG转换为PDF?
解决CairoSVG转换SVG时丢失嵌入图片的问题
问题重现
我在实现模板生成PDF的流程中,先将文档导出为SVG格式,再通过CairoSVG转换为PDF,但SVG中的<image>元素始终被静默丢弃:
- 无论是使用Data URL还是本地文件路径作为
href值 - 转换PDF、PNG甚至SVG输出时,仅保留矩形元素,嵌入图片完全消失
测试SVG代码:
<!-- test.svg --> <svg viewBox="0 0 1 1" width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <rect x="0" y="0" width="1" height="1" fill="green"/> <image x="0" y="0" width="1" height="1" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAATSURBVBhXYwCC/yACicZgMPwHAFnNBPyimoN0AAAAAElFTkSuQmCC"/> </svg>
Python测试代码:
import cairosvg cairosvg.svg2pdf(url='test.svg', write_to='out.pdf') cairosvg.svg2png(url='test.svg', write_to='out.png') cairosvg.svg2svg(url='test.svg', write_to='out.svg')
转换后的SVG输出(仅保留矩形):
<!-- out.svg --> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="75pt" height="75pt" viewBox="0 0 75 75" version="1.1"> <g id="surface7"> <rect x="0" y="0" width="75" height="75" style="fill:rgb(0%,50.196078%,0%);fill-opacity:1;stroke:none;"/> </g> </svg>
解决方案
1. 升级CairoSVG到最新版本
旧版本的CairoSVG对Data URL和<image>元素的支持存在缺陷,先升级到稳定版:
pip install --upgrade cairosvg
2. 兼容SVG命名空间与属性
CairoSVG对SVG 2.0的href属性支持更好,同时保留xlink:href兼容旧规范,修改<image>标签:
<image x="0" y="0" width="1" height="1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAATSURBVBhXYwCC/yACicZgMPwHAFnNBPyimoN0AAAAAElFTkSuQmCC" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAATSURBVBhXYwCC/yACicZgMPwHAFnNBPyimoN0AAAAAElFTkSuQmCC"/>
3. 配置本地资源加载路径(针对本地图片)
如果嵌入的是本地图片文件,需在调用CairoSVG时指定资源根目录,确保能正确找到图片:
import cairosvg from pathlib import Path # 指定SVG所在目录作为资源加载的根路径 cairosvg.svg2pdf( url='test.svg', write_to='out.pdf', parent_path=Path(__file__).resolve().parent )
4. 确保系统依赖库完整
CairoSVG依赖底层的Cairo和librsvg库,缺失图像处理组件会导致无法解析图片:
- Ubuntu/Debian:
sudo apt-get install libcairo2-dev libgirepository1.0-dev librsvg2-dev - macOS(Homebrew):
brew install cairo librsvg - Windows:
使用预编译的wheel包(pip install cairosvg通常会自动安装依赖),或手动安装GTK+环境。
验证
修改SVG并升级依赖后,重新运行测试代码,输出的PDF/PNG/SVG文件将正确包含嵌入的图片元素。
内容的提问来源于stack exchange,提问作者IWonderWhatThisAPIDoes
相关产品推荐
相关产品推荐

