こんにちは、すのくろです。
今回は、自分が少し私生活で困った「画像の余白作成」をpythonを使って解決した話についての記事です。
以下が概要になります。
・pythonのImage, osモジュールを使用して画像に余白生成
・今回はiMovieに対応した画像にするため全て16:9の比になるよう余白付け足し
・指定ファイルの画像を全て一括で余白を追加可能
・余白の色を自分好みに指定可能
それでは詳細について説明していきます!
背景
まず、今回この余白追加を行う経緯と適用事例について簡単に話します。
(具体的な手法をすぐ知りたい方はここは飛ばしてください。)
自分はプライベートで画像のスライドショーを作ることになり、
Appleの純正の画像動画編集アプリの「iMovie」で編集しました。
その際に、縦長の画像を使用するとアプリの方で勝手に横幅いっぱいになるまで画像がアップされてしまう不都合が生じました。
縦長画像↓
縦長画像を入れると真ん中周辺しか映せない↓
多少であれば、「Ken Burns」機能で位置やアップの度合いを変えられるのですが、
縦横比が圧倒的に縦に大きい場合(アスペクトが高い場合)は画像を使うのは少しためらいます。
そこで、画像を引き伸ばしたりすることなく、下記のように横に余白を追加して画像全体を表示させて後は好きなように「Ken Burns」機能でアップさせる場所やスライドショー中の画像の移動を自由度高く行えるようにしました。
一応、他の既存のアプリで余白を作成するものがないか調べましたが、
画像一枚ずつ行ったりしなければならないもの、
広告を見ないといけないもの、
などしか見当たらなかったので、今回スライドショーには数百枚の写真を使うため、ちまちま一枚ずつ余白追加するのは時間がかかりそうで無理だと判断しました。
そこで、Pythonを使って画像処理で一気に数百枚でも余白追加可能なコードを作成しました!
作成したプログラム
ここから本題です。
pythonの「Image」モジュールと「os」モジュールを使って、
どんなアスペクト比(縦横比)の画像に対しても、16:9になるように余白を追加するプログラムの例を紹介します。
①必要なモジュールのインポート
初めに今回必要なモジュール(ライブラリ)をインポートします。
from PIL import Image
import os
- Image: 画像処理のため
- os: ファイル名を取得するため
②アスペクト比に対して余白を作成する関数の作成
次に関数で画像に余白を追加するコードを作成します。
def expand(pil_img, background_color):
width, height = pil_img.size
if width/16 > height/9:
new_h = int(width/16*9)
result = Image.new(pil_img.mode, (width, new_h), background_color)
result.paste(pil_img, (0, (new_h - height)//2))
return result
else:
new_w = int(height/9*16)
result = Image.new(pil_img.mode, (new_w, height), background_color)
result.paste(pil_img, ((new_w - width) // 2, 0))
return result
- 関数名:「expand()」
- 引数1「pil_img」:画像ファイル名
- 引数2「background_color」:余白の色
if内の解説をします。
まず画像の縦と横の大きさを取得します。
その縦と横の比が16:9よりも大きいか小さいかで縦横のどちらかに余白を追加する処理を行なっています。
③フォルダやファイルの準備
関数ができた所で、次にファイルの準備をします。
実行したい画像ファイルを一つのフォルダに格納します。
今回のコードでは、上記のようにプログラムと同じディレクトリ内に「images」というフォルダを作りました。
その中に余白追加したい画像ファイルを5つ入れてあります。
次に、画像に余白を追加した新しい画像ファイルを入れていくフォルダも準備しておきます。
今回であれば、「images_new」というフォルダをプログラムと同じディレクトリに作成しました。
これでプログラム実行の準備はOKです。
④フォルダ内のファイルの読み込み
それでは、プログラムの方で、画像ファイル名を取得していきます。
コードは下記になります。
filename = "images"
filename2 = "images_new"
images = os.listdir(filename)
images
###出力結果###
# ['image4.png', 'image5.png', 'image1.png', 'image2.png', 'image3.png']
⑤余白追加の実行
最後に初めに作成した「expand()」関数を実行して画像に余白を追加していきます。
コードは下記です。
clist = ["LightYellow", "MistyRose", "LightBlue"]
bcolor = clist[1]
for img in images:
im = Image.open('{}/{}'.format(filename, img))
im_new = expand(im, bcolor)
im_new.convert('RGB').save('{}/new_{}'.format(filename2, img), quality=100)
まず、余白の色を指定してあげます。
自分の場合は色を状況に応じて変えたい時があったので、
「clist」というリストにいくつか色の名前をまとめておいて、
そのリストから指定して「bcolor」を実際に使う色としています。
その後はfor文を使って、画像ファイル一枚一枚に対して余白追加を実行しています。
- 画像ファイル名の取得
- 画像に余白追加
- 変更後のフォルダに保存
と言った流れを、for文内の3行で行なっています。
保存時に画質を「quality」指定しています。
今回は100%、つまり下の画像と同じ画質です。
今回の処理で下記のように画像に余白を追加できました。
余白追加後の画像をiMovieで使用すると↓のように、16:9の領域に画像全体をしっかり表示させることができました!
まとめ
今回は、画像に自分の好きなように余白を追加する方法について紹介しました。
広告があるような他のアプリを使わず、
pythonの画像処理系のモジュールを使うことで、自分で一気に数百枚の画像の余白を追加できました。
Pythonが使えると、思わぬ所で重宝することを実感しました。
pythonで何ができるかだけでも知っていることで、今回のように挑戦できるかと思います。
データサイエンスや効率化のためのPython学習に自分がかなり役立った書籍を参考までにお伝えします。
書籍で一度買って手元におくと、いつでも気軽に繰り返し見ることになり知識が定着しやすく、便利です。
また、今回のChatGPTのような新しい知識については、
Twitterやウェブで最新情報を収集して簡単に知りつつも、書籍で体系的に学ぶのもありだと思います。
また、プログラミングをより体系的にかつ爆速で学びたいと言う方向けに、おすすめのオンラインスクールを2つ厳選して紹介していますので、こちらもよければご覧ください!
以上、ここまでお読みいただき、ありがとうございました!
コメント