PythonでデータからPNG画像を生成したいアプリケーションがあります。私はいくつかの検索を行って、かなり古くなった "PIL"を見つけました。これのためにもっと良いライブラリがありますか?PythonでPNGファイルを作成する
おかげで、
PythonでデータからPNG画像を生成したいアプリケーションがあります。私はいくつかの検索を行って、かなり古くなった "PIL"を見つけました。これのためにもっと良いライブラリがありますか?PythonでPNGファイルを作成する
おかげで、
シンプルなPNGファイルは、純粋なPythonコードから非常に簡単に生成できます。標準のzlibモジュールと、チャンクを書き込むためのいくつかのバイトコードが必要です。ここでは、カジュアルリーダーが独自のpngジェネレータのスターターとして使用する可能性がある完全な例を示します:
#! /usr/bin/python
""" Converts a list of list into gray-scale PNG image. """
__copyright__ = "Copyright (C) 2014 Guido Draheim"
__licence__ = "Public Domain"
import zlib
import struct
def makeGrayPNG(data, height = None, width = None):
def I1(value):
return struct.pack("!B", value & (2**8-1))
def I4(value):
return struct.pack("!I", value & (2**32-1))
# compute width&height from data if not explicit
if height is None:
height = len(data) # rows
if width is None:
width = 0
for row in data:
if width < len(row):
width = len(row)
# generate these chunks depending on image type
makeIHDR = True
makeIDAT = True
makeIEND = True
png = b"\x89" + "PNG\r\n\x1A\n".encode('ascii')
if makeIHDR:
colortype = 0 # true gray image (no palette)
bitdepth = 8 # with one byte per pixel (0..255)
compression = 0 # zlib (no choice here)
filtertype = 0 # adaptive (each scanline seperately)
interlaced = 0 # no
IHDR = I4(width) + I4(height) + I1(bitdepth)
IHDR += I1(colortype) + I1(compression)
IHDR += I1(filtertype) + I1(interlaced)
block = "IHDR".encode('ascii') + IHDR
png += I4(len(IHDR)) + block + I4(zlib.crc32(block))
if makeIDAT:
raw = b""
for y in xrange(height):
raw += b"\0" # no filter for this scanline
for x in xrange(width):
c = b"\0" # default black pixel
if y < len(data) and x < len(data[y]):
c = I1(data[y][x])
raw += c
compressor = zlib.compressobj()
compressed = compressor.compress(raw)
compressed += compressor.flush() #!!
block = "IDAT".encode('ascii') + compressed
png += I4(len(compressed)) + block + I4(zlib.crc32(block))
if makeIEND:
block = "IEND".encode('ascii')
png += I4(0) + block + I4(zlib.crc32(block))
return png
def _example():
with open("cross3x3.png","wb") as f:
f.write(makeGrayPNG([[0,255,0],[255,255,255],[0,255,0]]))
OPを含むおそらく、私たちのほとんどよりも少し深いが、探しています。私がPNGでより深く掘り下げたいと思えば、これは素晴らしい参考資料です。 – mightypile
この例は素晴らしいです。パレットを追加する方法(いくつかの基本的な赤/緑/その他の色とアルファチャンネルがあります)を示すために変更することができますか? – 576i
私は非常に短い答えを提供したいと思っていました。明らかに、画像を構築してエンコードするためのかなりのオプションがあります。幸いなことに、PNG標準は各チャンク(https://www.w3.org/TR/PNG)に何を入れるべきかについてはっきりしています。ビットスタッフィングを避けるために、値を常に正確に1バイトにエンコードするオプションを探します。 /////非常にシンプルなRGBAの場合:PLTEチャンクにはエンコードオプションはありません。=>カラーチャンネルごとに常に正確に8ビットで、それ以上ではありません。したがって、各エントリは4バイト(R、G、B、A)です。 IHDRのビット深度はIDATを参照します.8ビットでインデックスバイトだけをもう一度書くことができます。 –
PILはどのように古くなっていますか? –
あなたは良い古いPILを使用しています(あなたがまだpy3.2を超えて開発していない場合) – joaquin