【问题标题】:How to convert SVG to PNG or JPEG in Python?如何在 Python 中将 SVG 转换为 PNG 或 JPEG?
【发布时间】:2018-12-29 05:08:11
【问题描述】:

我正在使用svgwrite 并生成 svg 文件,如何将它们转换为 PNG 或 JPEG?

【问题讨论】:

  • 我在 SO 中没有找到类似的问题。赞成。
  • 这里似乎有你的问题的答案:stackoverflow.com/questions/6589358/…
  • 但是……这是另一个库,对吧?但也许你需要它。
  • @qräbnö 好吧,既然 svgwrite 似乎不能处理 svg 到 png 的转换,那么……是的,你需要另一个库。同样问题的另一个例子也可以在这里找到:stackoverflow.com/questions/2932408/…

标签: python svg png jpeg svgwrite


【解决方案1】:

pyvips 支持 SVG 加载。它免费、快速、占用内存少,可在 macOS、Windows 和 Linux 上运行。

你可以这样使用它:

import pyvips

image = pyvips.Image.new_from_file("something.svg", dpi=300)
image.write_to_file("x.png")

默认 DPI 为 72,可能有点低,但您可以设置任何您喜欢的 DPI。您可以通过明显的方式写入 JPG。

你也可以像这样按你想要的像素尺寸加载:

import pyvips

image = pyvips.Image.thumbnail("something.svg", 200, height=300)
image.write_to_file("x.png")

这将渲染 SVG 以适应 200 x 300 像素的框。 docs introduce all the options

pyvips SVG 加载器有一些不错的属性:

  • 它使用 librsvg 进行实际渲染,因此 PNG 将具有高质量的抗锯齿边缘。
  • 它比 ImageMagick 之类的系统快得多,ImageMagick 只是简单地使用 inkscape 进行渲染。
  • 它支持渐进式渲染。大图像(每边超过几千个像素)会分段渲染,从而控制内存使用,即使对于非常大的图像也是如此。
  • 它支持流式传输,因此您可以将 SVG 直接渲染到一个巨大的 Deep Zoom 金字塔(例如),而无需任何中间存储。
  • 它支持来自内存区域、字符串和管道以及文件的输入。

从字符串渲染可以很方便,例如:

import pyvips

x = pyvips.Image.svgload_buffer(b"""
<svg viewBox="0 0 200 200">
  <circle r="100" cx="100" cy="100" fill="#900"/>
</svg>
""")

x.write_to_file("x.png")

【讨论】:

【解决方案2】:

对于将svg转换为png,我可以想到两种方法:

1。 这是可以满足您需求的 lib:https://cairosvg.org/documentation/

$ pip3 install cairosvg

python3代码:

cairosvg.svg2png(url="/path/to/input.svg", write_to="/tmp/output.png")

已在 linux(debian 9+ 和 ubuntu 18+)和 MacOS 上使用过它。对于大约 1MB svg 的大文件,它可以正常工作。例如:世界地图。 Lib 还允许导出 pdf 文件。

提示:cairosvg 提供 png 输出图像的放大功能,因为在使用矢量图形 svg 后默认大小看起来很模糊 :) 。我无法让 DPI 选项为我工作。

2。 还有另一种方法可以通过使用浏览器打开 svg 文件并使用 Selenium webdriver 与 Firefox 或其他浏览器进行截图。您可以将屏幕截图保存为 png。

可以使用 Pillow 将 png 转换为 jpeg:Convert png to jpeg using Pillow

【讨论】:

    【解决方案3】:

    在 Windows 上,您在尝试导入 pyvips 时会遇到 libgobject-2.0-0.dll、libvips-42.dll 等错误。要让 pyvips 在 Windows 上运行,请执行以下操作:

    在代码中这样做:

    import os
    
    # The bin folder has the DLLs
    os.environ['path'] += r';C:\Path\ToYour\VIPsFolder\bin'
    
    import pyvips
    
    image = pyvips.Image.thumbnail("test.svg", 200)
    image.write_to_file("test.png")
    

    我建议在 cairosvg 上使用 pyvips。根据我的测试,它比 cairosvg 快得多,尤其是对于大型 SVG。无论如何,您需要与上述类似的东西才能让 cairosvg 在 Windows 上运行。

    【讨论】:

      【解决方案4】:

      我查看了几种方法,包括 cairo(我无法使其在 Windows 上运行)、svglib+reportlab(无法更改 dpi)甚至是 inkscape(从命令行)。

      最后这是我找到的最好的方法。我在 python 3.7 上测试过。

      def convert(method, svg_file, png_file, resolution = 72):
          from wand.api import library
          import wand.color
          import wand.image
      
          with open(svg_file, "r") as svg_file:
              with wand.image.Image() as image:
                  with wand.color.Color('transparent') as background_color:
                      library.MagickSetBackgroundColor(image.wand, 
                                                       background_color.resource) 
                  svg_blob = svg_file.read().encode('utf-8')
                  image.read(blob=svg_blob, resolution = resolution)
                  png_image = image.make_blob("png32")
      
          with open(png_file, "wb") as out:
              out.write(png_image)
      

      我必须安装 wand 包(使用 pip),然后安装 ImageMagick for Windows (http://docs.wand-py.org/en/latest/guide/install.html#install-imagemagick-on-windows)。

      【讨论】:

        猜你喜欢
        • 2011-09-09
        • 2019-10-17
        • 2012-02-17
        • 2022-08-22
        • 2020-03-13
        • 1970-01-01
        • 2015-01-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多