我的目标是在黑色图像上绘制一些多边形,使生成的图像的总尺寸尽可能小。
所以我在 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>
您可以像这样将 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/