【Python】RGB配列からGIF画像を作成して、Jupyter Notebookに表示する方法
0. はじめに
先日書いたPyBulletの調査記事の中で利用したGIF画像の作成・表示の方法をまとめておきます。
1. RGB配列からGIF画像を作成する方法
RGB配列をGIF画像にするのに、Pillowを利用します。
多くのライブラリで利用されているので、環境によってはインストール済みであることもあると思いますが、もし未インストールであれば、PyPIにホストされているので、pip で簡単にインストールできます。
pip install Pillow
少しややこしいですが、Pillow は PIL (Python Image Library) を forkしているため、プログラム内で利用するパッケージ名は PIL
になっています。
GIFにしたい画像の各フレームに対して Image
クラスの静的メソッドのImage.fromarray
を利用することで、RGB配列から画像を構築します。
少し不思議かもしれませんが、最初のフレーム画像に対して、Image.save
メソッドを実行し、残りのフレームは引数append_images
に渡します。
引数loop
によって繰り返し回数を指定できます。(loop=0
は無限ループ)
保存したいファイル名の拡張子を .gif
にすることで、GIF形式だと認識してくれますが、format="gif"
と明確に指定することもできます。
from PIL import Image
gif = []
for _ in range():
rgb = ... # なにかの処理でRGB配列を作成
gif.append(Image.fromarray(rgb))
gif[0].save("mygif.gif", save_all=True, append_images=gif[1:], loop=0)
2. Jupyter Notebookに表示する方法
Jupyter Notebook (およびGoogle Colaboratory 等の類似の環境) で、GIF画像を表示するには、画像情報をBase64エンコーディングしてHTMLコンポーネントとして表示します。
import base64
from IPython import display as dd # display関数と名前が被るので別名にしておきます。
with open("mygif.gif", "rb") as f
b64 = base64.b64encode(f.read()).decode("ascii")
display(dd.HTML(f'<img src="data:image/gif;base64,{b64}" />'))
3. ファイルに書き出さない方法
作成したファイルをすぐ読み出すだけにしか利用しないのであれば、そもそもファイルに書き出さなくても良いのでは?というニーズがあると思います。
Image.save
にstr
型のファイル名を渡しましたが、file-likeオブジェクト(厳密には、write
・tell
・seek
を持つ)を代わりに渡すことができるので、io.BytesIO
クラスを利用することができます。
基本的には同じですが、書き出した後にディスク位置が最後尾のままなので、読み出す前にseek(0)
で先頭に持ってこないと、read
しても何も読みだせません。
import base64
import io
from PIL import Image
from IPython import display as dd
gif = []
for _ in range():
rgb = ... # なにかの処理でRGB配列を作成
gif.append(Image.fromarray(rgb))
f = io.BytesIO()
gif[0].save(f, save_all=True, append_images=gif[1:],format="gif", loop=0)
f.seek(0)
b64 = base64.b64encode(f.read()).decode('ascii')
f.close()
display(dd.HTML(f'<img src="data:image/gif;base64,{b64}" />'))
4. おわりに
Pythonで、RGB配列からGIFを作成して、Jupyter Notebookに表示する方法をまとめました。
リストとして画像配列を全部保持せずに、ファイルに逐次書き出していく方式もあるのじゃないだろうかと思いますが、今回はそこまでは調べませんでした。GIFぐらいの短い長さであれば、リストとして保持していてもそこまで問題は無いと感じたからです。
Discussion