【Python】あみだくじの当選過程をアニメーション化してみた

こんにちは、ヒガシです。

 

今回は前回作成したあみだくじプログラムをさらに改良し、作成したあみだくじの当選過程をアニメーション化する方法をご紹介したいと思います。

 

完成物としては以下のような感じですね。

 

こんなものが作れても何の意味もありませんが、こいつを作る過程で様々なスキルを習得することができるはずです。

 

ぜひトライしてみてください。

 

それではさっそくやっていきましょう!

 

スポンサーリンク

必要なライブラリ一覧

今回は前回と同様にnumpyとPillowのみを使用していきます。

 

以下のコードが通るかどうか確認してみましょう。

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import numpy as np

 

スポンサーリンク

あみだくじの当選アニメーションの作り方

それでは冒頭に紹介したようなアニメーションを作成する方法をご紹介していきます。

 

以下がそのコードです。

※前回紹介したあみだくじ画像をつくるところから記述しています。

#ライブラリインポート
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import numpy as np

#情報入力
list=['AA','BB','CC','DD','EE']
bar_horizontal=12
#文字サイズ、色、画像サイズ等の指定
font_size=50
font_color=255
line_w=5
h=750
w=1000
font_path="C:\Windows\Fonts\HGRPP1.TTC"
font = ImageFont.truetype(font_path, font_size) 
bar_vertical=len(list)
width_h=int((h-400)/bar_horizontal)
width_w=int(w/bar_vertical)

#ベース画像の作成
img=Image.new("L",(w+width_w,h+width_h))
#PillowからNumPyへの変換
base_img=np.array(img)

#あみだの線を描写する
for i in range(bar_vertical):
    base_img[width_h+100:-width_h-100,(i+1)*width_w-line_w:(i+1)*width_w+line_w]=150
for i in range(bar_horizontal):
    pos=np.random.randint(1,bar_vertical)
    base_img[width_h+200+int((i+1)*width_h-line_w):width_h+200+int((i+1)*width_h+line_w),pos*width_w:(pos+1)*width_w]=150

#NumPyからPillowへの変換
img=Image.fromarray(base_img)
#候補初リストを描写する
for i in range(bar_vertical):
    ImageDraw.Draw(img).text(((i+1)*width_w-12*len(list[i]), 50), list[i], font = font , fill = font_color)
election=np.random.randint(0,bar_vertical)
ImageDraw.Draw(img).text(((election+1)*width_w-25, h-100), '★', font = font , fill = font_color)
base_img=np.array(img)

pictures=[]
#★を移動させる関数
def show_pic(base_img,hpos,wpos,n):
    img=Image.fromarray(base_img)
    ImageDraw.Draw(img).text((wpos-25, hpos-25), '★', font = font , fill = font_color)
    pictures.append(img.convert('P'))

#★マークの移動
wpos=int((election+1)*width_w)
spos=30
n=0
for i in range(h-width_h-100+25,width_h+100,-line_w*2):
    hpos=i
    #上に進む
    if base_img[i,wpos-spos]<100 and base_img[i,wpos+spos]<100: 
        show_pic(base_img,hpos,wpos,n)
        n+=1 
    #左に進む
    elif base_img[i,wpos-spos]>100:
        j=0
        while base_img[i,wpos-j]>100:
            j+=1
            if j%(line_w*2)==0:
                show_pic(base_img,hpos,wpos-j,n)
                n+=1
        i+=10
        wpos=wpos-j+line_w
    #右に進む
    else:
        j=0
        while base_img[i,wpos+j]>100:
            j+=1
            if j%(line_w*2)==0:
                show_pic(base_img,hpos,wpos+j,n)
                n+=1
        wpos=wpos+j-line_w
#gifアニメを出力する
pictures[0].save('anime.gif',save_all=True, append_images=pictures[1:],
optimize=False, duration=20, loop=0)

 

前回同様にあなたが設定すべきところは8行目の当選候補者のリストを作成するところだけです。

 

基本的には適当にあみだくじを作成し、★マークがある場所から画像の輝度情報をもとに上方向に探索し、左右どちらかに横棒が存在する場合はその方向に進む、突き当りにあたったらまた上方向に探索を再開する、ということを繰り替えし実行しているだけです。

 

また、その探索過程での状態を随時画像として保存しておき、探索終了後にgifアニメ化するという処理を実行しています。

 

最初は難しいと感じると思いますが、ひとつひとつコードを追いかけていけば何をやっているか理解できるはずです。

 

スポンサーリンク

サンプルコードの実行結果確認

それでは先ほどのコードを実行してみましょう。

まずは何も変更しないで実行してみます。

冒頭に紹介したように問題なくアニメーション化できていますね。

 

つぎは候補者を

list=[‘AA’,’BB’,’CC’,’DD’,’EE’,’FF’,’GG’,’HH’,’II’]

に変更し、さらにbar_horizontal(横線の数)=40、line_w(線の太さ)=3、h(画像の高さ)=1000に変更して実行してみます。

 

以下が作成された動画です。

こんな感じで設定を変更しても問題なく対応できていますね。

 

スポンサーリンク

おわりに

というわけで今回はpythonを使って、データのヒストグラム(頻度分布)を作成する方法をご紹介しました。

 

データ分析の際などにぜひご活用ください。

 

このように、私のブログでは様々なスキルを紹介しています。

過去記事一覧

 

今は仕事中で時間がないかもしれませんが、ぜひ通勤時間中などに他の記事も読んでいただけると嬉しいです。
⇒興味をもった方は【ヒガサラ】で検索してみてください。

確実にスキルアップできるはずです。

 

最後に、この記事が役に立ったという方は、ぜひ応援よろしくお願いします。
↓ 応援ボタン
にほんブログ村 IT技術ブログへ
にほんブログ村

それではまた!

コメント

タイトルとURLをコピーしました