PILでPNG画像を文字列に書き込む方法は?


99

PILを使用して画像を生成しました。メモリ内の文字列に保存するにはどうすればよいですか?このImage.save()メソッドにはファイルが必要です。

このような画像をいくつか辞書に保存したいのですが。

回答:


194

BytesIOクラスを使用して、ファイルのように動作する文字列のラッパーを取得できます。BytesIOオブジェクトは、ファイルと同じインタフェースを提供しますが、単にメモリの内容を保存します。

import io

with io.BytesIO() as output:
    image.save(output, format="GIF")
    contents = output.getvalue()

formatパラメータで出力形式を明示的に指定する必要があります。明示的に指定しないと、PILが自動的に検出しようとするとエラーが発生します。

ファイルから画像をロードした場合format、元のファイル形式を含むパラメーターがあるため、この場合はを使用できますformat=image.format

ioモジュールを導入する前の古いPython 2バージョンでは、StringIO代わりにモジュールを使用していました。


1
はい!これはまさに私が探していたものです。私はpython、string、reader、writer、bufferのすべての組み合わせをググってみましたが、何も思いつきませんでした。ありがとう!
rik.the.vik 09

2
動作しません:( Imaging / PIL / Image.pyc行1423でこのKeyErrorが発生しました-> KeyError(ext)を発生させます#不明な拡張子
Radian

6
@ Radian、save()メソッドに関するPILのドキュメントによると:You can use a file object instead of a filename. In this case, you must always specify the format.最初の引数がファイルオブジェクトの場合、2番目の引数を渡す必要があります。これは形式(例:)'PNG'です。
Su Zhang

1
現在のPythonのバージョンでは、StringIOをはIOパッケージである、あなたが書く必要があります:from io import StringIO
Spoutnik16

4
あなたはもっと使うことができますimage.save(output, format=image.format)
reetesh11 2017年


24

sthの解決策は私にとってうまくいきませんでし
た...

Imaging / PIL / Image.pyc line 1423-> raise KeyError(ext)#unknown extension

StringIOの場合には存在しないfilenameの拡張子からフォーマットを検出しようとしました

パラメータでフォーマットを自分で設定することで、フォーマット検出をバイパスできます

import StringIO
output = StringIO.StringIO()
format = 'PNG' # or 'JPEG' or whatever you want
image.save(output, format)
contents = output.getvalue()
output.close()

14

save()ファイルのようなオブジェクトとパスを使用できるため、次のようにメモリ内バッファを使用できますStringIO

buf = StringIO.StringIO()
im.save(buf, format='JPEG')
jpeg = buf.getvalue()

ありがとうございました。StringIO-それが私が必要とするものです。
maxp 2009年

save()インターフェースは、PNG、JPEG、または実際のファイル形式を取得する場合、tostring()インターフェースよりもはるかにクリーンです。
Kekoa 2010年

13

最新(2017年半ばのPython 3.5およびPillow 4.0以降):

StringIOは、以前のように機能しないようです。BytesIOクラスは、これを処理する適切な方法です。Pillowの保存関数は、最初の引数として文字列を想定しており、驚くことにStringIOをそのように認識していません。以下は、以前のStringIOソリューションに似ていますが、代わりにBytesIOがあります。

from io import BytesIO
from PIL import Image

image = Image.open("a_file.png")
faux_file = BytesIO()
image.save(faux_file, 'png')

2
image_data = faux_file.getvalue()の目的は何ですか?
Ryan

@ライアングッドキャッチ、全く目的なし。テストから取り残され、ようやく削除されました。
マイティパイル

9

「このような画像を辞書に保存したい」という場合、これがメモリ内の構造かどうかはわかりません。

メモリ内の画像を柔らかくするためにこれを行う必要はありません。imageオブジェクトを辞書に保存するだけです。

辞書をファイルに書き込む場合は、im.tostring()メソッドとImage.fromstring()関数を確認することをお勧めします

http://effbot.org/imagingbook/image.htm

im.tostring()=>文字列

標準の「生」エンコーダーを使用して、ピクセルデータを含む文字列を返します。

Image.fromstring(mode、size、data)=>画像

標準の「生」デコーダーを使用して、文字列のピクセルデータから画像メモリを作成します。

「フォーマット」(.jpeg、.pngなど)は、ファイルを交換する場合にのみディスク上で重要です。ファイルを交換しない場合は、フォーマットは重要ではありません。


2
彼は、PNG形式を保持したい、生のピクセルデータに縮小したくないようです。
Ben Blank
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.