python : gifの作成(アニメーション)

pythonを使って、gifの作成方法です。

gifは正式にはジフと読むとのことで、開発者のかたが、

ジフだ!って言ってそうなったそうです。下記の略です。

Graphics Interchange Format

 

今日会社で報告書を作る際に、書いた3Dでの図面を載せるときに

アニメーションにしたら見やすいかな~と思い、

gifの作り方を調べてつくったのですが、wordには貼れず・・・

 

というわけで1時間ぐらい無駄に過ごしてしまいましたが、

とりあえず、ざっくりとは使い方がわかったので載せておきます。

後々なにか使うかもしれませんしね。

 

今回のgifファイルの作り方としては、

opencvで画像を作って、Pillowでgifファイルに変換という方法です。

pillowで作ろうとするとopencvのファイルを

pillow用に変換しなければならないのですが、これが割と苦戦しました。

 

プログラムです。まずはモジュール

import cv2

from PIL import Image

 

昨日の記事(描画方法)を使ってgifファイルを作ります。

こんなファイルになります。

f:id:Kangkang1981:20200319223111g:plain

gifファイルはアニメーションですので、

画像を連続して表示するものとなるので、

この画像を収納するリストを作ります。

images = []

 

流れとしては、opencvの画像を用意(とか言いながらnumpyで空画像を作っています)

img = np.full((250, 600, 3), 128, dtype=np.uint8)

cv2.rectangle(img, (10, 10), (110, 110), (0, 255, 0), thickness=1)
cv2.rectangle(img, (10, 120), (110, 220), (255, 0, 0), thickness=-1)

 

これをpillowで読める形式に変換

new_img = Image.fromarray(img)

これをリストに入れる

images.append(new_img)

 

これを何回か繰り返して、下記のように書きます。

images[0].save('output.gif',save_all=True, append_images=images[1:], optimize=False, loop=0)

 

この引数としては

'output.gif'

保存する際のファイル名です。

 

append_images 

これ最初のフレーム画像に対して、残りの画像リストを渡すという因数です。

基本的には、上のように、最初をimage[0].saveとして、次から返しということで、

append_images=images[1:]とすればよいです。

 

loop

これは再生回数で0にすると無限に再生してくれます。

後の、save_all , optimizeの2つはよくわかっていないです。

TrueにしたりFalseにすると何か変わるかもしれないというぐらいの理解です。

 

プログラムは下記です。

 

import cv2
import numpy as np
from PIL import Image

images = []

#描画する画像を作る,128を変えると色を変えれます 0黒→255白
img = np.full((250, 600, 3), 128, dtype=np.uint8)

new_img = Image.fromarray(img)
images.append(new_img)

#長方形,描画する画像,座標1点目、座標2点目、色、線の太さ(-1は塗りつぶし)
cv2.rectangle(img, (10, 10), (110, 110), (0, 255, 0), thickness=1)
cv2.rectangle(img, (10, 120), (110, 220), (255, 0, 0), thickness=-1)

new_img = Image.fromarray(img)
images.append(new_img)


#線、描画する画像を指定、座標1点目、2点目、色、線の太さ
cv2.line(img, (120, 10), (220, 110), (255, 255, 255), thickness=1)

new_img = Image.fromarray(img)
images.append(new_img)

#円、描画する画像を指定、座標(x,y),半径、色、線の太さ(-1は塗りつぶし)
cv2.circle(img, (300,60), 50, (0,0,255), thickness=5)
cv2.circle(img, (300,170), 50, (0,0,255), thickness=-1)

new_img = Image.fromarray(img)
images.append(new_img)

#楕円、描画する画像を指定、座標(x,y),xyの半径、角度,色、線の太さ(-1は塗りつぶし)
cv2.ellipse(img, ((400, 60), (10, 50), 0), (255, 255, 255),thickness=1)
cv2.ellipse(img, ((400, 170), (50, 50), 0), (255, 255, 255),thickness=-1)
cv2.ellipse(img, ((500, 60), (50, 10), 0), (255, 255, 255),thickness=1)
cv2.ellipse(img, ((500, 170), (50, 10), 30), (255, 255, 255),thickness=-1)

new_img = Image.fromarray(img)
images.append(new_img)

#cv2.imshow('img',img)
#cv2.imwrite('form.jpg',img)
images[0].save('output.gif',save_all=True, append_images=images[1:], optimize=False, loop=0)

 

今までにpythonについて書いた記事はここにリンクを貼ってあります。

興味があればぜひご覧ください。