python - 如何使用 PIL 优化调色板图像大小?

标签 python image python-imaging-library

我的目标是在黑色图像上绘制一些多边形,使生成的图像的总尺寸尽可能小。

所以我在 wiki 上阅读了一篇关于索引颜色的文章(link),这对我来说似乎是一个不错的选择(因为我应该只支持黑色和其他 5 种颜色,即总共 6 种颜色)和png 图像格式应支持“P”模式(即 palette images)。

这就是我创建这段代码的原因,以查看我将获得 6 种颜色和 1224x1024 图像的图像大小:

from PIL import Image, ImageDraw
# Create a black 1224x1024 image
img = Image.new('P', (1224, 1024))
img.putpalette([
    0, 0, 0,  # black background
    236, 98, 98, # red color
    236, 98, 97,
    236, 98, 96,
    236, 98, 95,
    236, 98, 94,
])

draw = ImageDraw.Draw(img)
# Draw a random red polygon at the top left corner of the image
draw.polygon(xy=list(1,1,2,2,3,3,4,4), fill=1)
del draw

img.save('1.png', format='PNG')

结果图像大小为 768 字节,这对我来说似乎太多了。

有什么我可以在我的代码中修正以使结果图像尺寸更小吗?

最佳答案

768 字节对我来说代表一张 1.2 兆像素的图像并不合理。您可以尝试通过 pngcrush 运行 PIL 生成的文件,如下所示,看看它是否可以削减几个字节:

pngcrush input.png result.png

如果你真的只想在黑色背景上画几个纯色的多边形,我建议你看看矢量格式,比如 SVG example here而不是光栅格式 PNG et al

您还可以使用 rsvg如果需要,可以将 SVG 图像渲染为 PNG,但从您的问题中您的应用程序和需要如此小的图像的原因都不清楚,所以我不知道这是否适合您。

这是一个 300 字节的 SVG 图像,具有黑色背景、2 个矩形和一个多边形,如左上角的红色星形:

<svg width="1224" height="1024">
  <rect width="100%" height="100%" fill="black"/>
  <polygon points="9.9, 1.1, 3.3, 21.78, 19.8, 8.58, 0, 8.58, 16.5, 21.78" fill="red"/>
  <rect x="100" y="200" width="100" height="400" fill="blue"/>
  <rect x="800" y="280" width="100" height="200" fill="lime"/>
</svg>

enter image description here


您可以像这样将 SVG 加载到 Numpy 数组中:

#!/usr/bin/env python3

import cairosvg
import io
from PIL import Image

def svgRead(filename):
   """Load an SVG file and return image in Numpy array"""
   # Make memory buffer
   mem = io.BytesIO()
   # Convert SVG to PNG in memory
   cairosvg.svg2png(url=filename, write_to=mem)
   # Convert PNG to Numpy array
   return np.array(Image.open(mem))

# Read SVG file into Numpy array
res = svgRead('image.svg')

如果您执意要使文件更小,但以降低与其他图像查看器的兼容性为代价,您可以设计自己的非常简单的格式,有点类似于 SVG,这样您就可以存储由 SVG 表示的图像我给出的示例是一个简单的文本文件:

b,1224,1024,#00000
r,100,200,100,400,#0000ff
r,800,280,100,200,#00ff00
p,9.9,1.1,3.3,21.78,19.8,8.58,0,8.58,16.5,21.78,#ff0000

然后我创建了 127 个字节。


您可以通过将 SVG 文件加载到任何网络浏览器来查看它们,或者在终端中使用 ImageMagick 将其转换为 PNG,如下所示:

magick input.svg result.png

关于python - 如何使用 PIL 优化调色板图像大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55440483/

相关文章:

python - python高效读取数据(仅一行)

javascript - 使用javascript单击缩略图时临时加载图像和图像选择

python - 运行我的 Python 脚本时出错

python - PIL简单渐变和TypeError : an integer is required

python - PIL 的舍入误差

python - 如何计算数据框列每月的下降次数

Ubuntu 中的 Python-MySQLdb 错误

python - 如何检查 pygame 上的天气或大写锁定是否打开

javascript - 在javascript中呈现像视频一样的图像链

html - 如何在 div 中居中(背景)图像?