You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中将Pygal生成的图片URI转换为Pillow可处理的图像

我来帮你搞定这个把Pygal生成的data URI转换成Pillow可处理图像的问题~你的代码目前只是把整个URI字符串转成了字节,但没正确提取和解码里面的图像数据,这就是为啥失败啦。下面给你拆解问题,再附上完整的解决代码:

问题根源

Pygal的render_data_uri()返回的是data URI格式的字符串,长这样:data:image/svg+xml;base64,xxxxxxxxx。逗号后面的那串才是经过base64编码的SVG图像数据,我们得先把这部分抠出来解码,才能得到Pillow能认的内容。另外要提一句:Pillow原生处理SVG需要额外依赖,所以给你准备了两种方案,按需选就行。

方案1:直接用Pillow加载SVG(需环境支持)

先确保你的环境能让Pillow处理SVG:

  • Linux:先装系统依赖sudo apt-get install librsvg2-dev,然后重新装Pillow:pip install --upgrade pillow
  • macOS:用Homebrew装brew install librsvg,再重装Pillow
  • Windows:可以找预编译的Pillow包(比如Unofficial Windows Binaries的版本),或者直接用方案2

修正后的完整代码:

import pygal
import base64
from PIL import Image
from io import BytesIO

# 获取调查人数
user_num = int(input("How many people are taking the survey?"))
print()

# 用字典存颜色计数,比单独变量简洁多了
colour_counts = {"red":0, "orange":0, "yellow":0, "green":0, "blue":0, "purple":0}

# 收集用户输入的颜色
for x in range(1, user_num + 1):
    # 转小写,兼容用户输入的大小写(比如Red/RED都能识别)
    user_colour = input("What is your favourite colour?").lower()
    print()
    if user_colour in colour_counts:
        colour_counts[user_colour] += 1

# 生成柱状图
bar_chart = pygal.Bar()
bar_chart.title = "Favourite Colour"
bar_chart.x_labels = ("Red", "Orange", "Yellow", "Green", "Blue", "Purple")
bar_chart.add('Favourite Colours', list(colour_counts.values()))

# 获取data URI并处理
data_uri = bar_chart.render_data_uri()

# 提取base64编码部分(把逗号前面的前缀去掉)
base64_data = data_uri.split(',')[1]
# 解码base64得到SVG的字节数据
svg_bytes = base64.b64decode(base64_data)
# 把字节转成BytesIO对象,Pillow才能读
svg_io = BytesIO(svg_bytes)

# 用Pillow打开SVG并操作
try:
    img = Image.open(svg_io)
    # 可以直接显示图像
    img.show()
    # 也可以保存成PNG文件
    img.save("favourite_colours.png")
except Exception as e:
    print(f"加载SVG失败啦:{e},试试下面的方案2吧")

方案2:用svglib转成PIL图像(兼容性拉满)

要是装Pillow的SVG依赖太麻烦,就用svglib库,它专门干SVG转PIL图像的活儿:

  1. 先装库:pip install svglib pillow
  2. 把代码里的图像处理部分换成下面这段:
# ...前面的图表生成、data URI处理和方案1完全一样...

from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM

# 把SVG字节转成BytesIO,传给svglib
drawing = svg2rlg(BytesIO(svg_bytes))
# 渲染成PIL图像
img = renderPM.drawToPIL(drawing)

# 显示或保存图像
img.show()
img.save("favourite_colours.png")

额外小优化

我把你原来的单个颜色变量改成字典了,代码更简洁,还加了.lower()处理用户输入,不管用户输Red、RED还是red都能正确计数~

这样操作后,你就能顺利把Pygal的图表转换成Pillow能处理的图像啦!

内容的提问来源于stack exchange,提问作者Infinity

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:30:10