Introduction
画像認識とかに使うわけではありません・・・・・
きっかけ
AviUtlという無料の動画編集ソフトで動画を作成する際に、画像のサイズがばらばらだと使いづらいので毎回いちいち手作業で直していましたが、面倒なので画像のサイズ変更を自動で行おうと思ったですまる
自己紹介→いつものやつ
Cf.)AviUtlについて
フリー動画編集ソフトにもかかわらず、有料ソフトにも引けをとらないレベルの編集が可能なのですが、使い方がなかなか難しいです。まぁそれなりのエンジニアにとっては、初心者が陥りやすいディレクトリ構造やインストールといったポイントは、プログラミングで培われた経験で代替できるレベルなので頭を悩ませるほどではないです。
対象者
・画像サイズをたくさん変更したい人
・画像を同じサイズに変更したい人
・1を聞いて10を理解できるエンジニア
・Windowsの人
非対象者
・三枚くらい画像サイズを変更したい人
・画像を一枚一枚いろんなサイズに変更したい人
・説明下手な筆者を攻撃しようとするエンジニア
・Macの人
Let's Start
このサイトにお世話になりました。
上記のサイトを軸にわからないとこなどで適宜調べたもの、エラー対処などをまとめておきます。
それでは張り切ってまいりましょう。
画像処理ライブラリ
Pythonの画像処理ライブラリとしてPillow(PIL)やOpenCVがあるそうですが、簡単な処理くらいならPillowのほうがやりやすいとのことで、今回はPillowでの方法を紹介します。
pip install pillow
pipでインストールできます。
Pillowの中でもImageというライブラリを使います。
cf) 似たライブラリにImageFileというものがありますが、大きな画像を使うときにBetterなようです。
よくわからないので詳しい人教えてください。
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
本題に戻ります!
画像のサイズを変える
参考情報のサイトに書いてある通りなんですが、画像のサイズを変えるには以下のコードでできます。画像サイズを1280*960に変更します。
from PIL import Image
img = Image.open('data/src/lena_square.png')
img_resize = img.resize((1280, 960))
img_resize.save('data/dst/lena_pillow_resize_nearest.jpg')
Image.open()で画像ファイルを開くことができます。
ここに画像ファイルのパスを入れましょう。
パスについて
一枚の画像サイズを変えたいんじゃない。
特定のディレクトリ内の画像をすべて置き換えたいんだ。
そう思っている同士諸君。気持ちはよくわかる。
そのためにまずはパスというものについて理解してほしい。
大丈夫。僕も全く理解はできていない。
この記事を作った理由の一つが、もっとくわしいひとにパスについて教えてほしくて書いているなんてのはもちろん内緒です
作業したいディレクトリをプログラムに教えてあげましょう。
path = 'C:\\Users\\Semple\\WorkingSpace'
もちろん上記のパスはおのおの違うと思いますので、皆さんのパソコン事情に合わせて変えてください。今回はわかりやすくするためにSempleディレクトリの下に作業場ディレクトリを作成しております。作業場ディレクトリの中にたくさんのjpeg形式の画像が保管してあります。
pathのライブラリとしては、os.pathという形式とpathlibという方法があるそうです。
最近ではpathlibという手法がはやりという記事を見ましたので、参考サイトのほうではos.pathという記述ですが、pathlibという方法に置き換えて記述しています。
参考サイト→https://note.nkmk.me/python-pathlib-mkdir-rmdir/
Sample Code
from PIL import Image
import pathlib
import glob
path = "C:\\Users\\Semple\\WorkingSpace\\*.jpg"
new_path = "C:\\Users\\Semple\\WorkingSpace\\SaveArea"
# ディレクトリがない場合は作る
if pathlib.Path(new_path).exists() == False:
pathlib.Path(new_path).mkdir()
files = glob.glob(path)
for file in files:
#file名を取得
file_list = pathlib.Path(file).name
#拡張子より前を取得
ftitle = pathlib.Path(file_list).stem
#拡張子の取得
ftype = pathlib.Path(file_list).suffix
#file名に_1を追加
new_filename = ftitle + "_1" + ftype
#処理する画像を選択
img = Image.open(file)
#サイズを変更する
img_resize = img.resize((1280, 960))
#別のディレクトリ下に保存する
save_path = pathlib.Path(new_path) / new_filename
#jpg形式で保存する。
img_resize.save(save_path,"jpeg")
Sample Codeの説明
・pathのWorkingSpace下にある*.jpgというものは、ディレクトリ内のすべてのjpeg画像を表しています。
・サイズを変えた画像は新しいディレクトリに保存するために、new_pathで別のディレクトリを指定しています。
・globについてはよくわかってません。
・新しいファイル名はわかりやすいように名前を少し変えています。
問題点
これからの改善点や現状の問題点
1,できない形式がある。
いま主流のiphoneでは、「.heic」という形式で画像が保存されます。
今調べている最中です。今後追記していきたいです。
2,画像の縦横比がおかしくなる
基本的に横長画像だけを処理していたので、気づかなかったのですが画像サイズを1280*960固定しているので、縦長画像があると縦につぶした画像が出来上がってしまいます。
格好が悪いので、お気をつけてください…
縦長画像が来たら処理をしないなどの条件分岐は作れるのですが、単純なスキップは望ましい解決策ではなくて…いいアイデアが思い浮かびません…。
3,jpegでもできない場合がある。
OSError: cannot identify image file
普通にプログラムが動いているはずなのに、たまに上のようなエラーを吐いて止まってしまう。
ひとまず例外処理でスキップしていますが、原因究明をしていきたいです。
今後追記していきたいです。
try:
Sample Code省略
except OSError:
print(file + "はOSErrorだよ")
pass
4,globについて
まだ説明できるほど理解できていません。動くのでひとまず後回しです。
ほかの問題点を先に解決したいです。
問題点については随時解決しだい追記していきます。
参考情報
pathlibの公式Doc→https://docs.python.jp/3/library/pathlib.html
Pathlibチートシート→https://qiita.com/meznat/items/a1cc61edb1e340d0b1a2
pathlibとos.pathの書き換え方法→https://mick3355-dev.hatenablog.com/entry/2018/03/16/112546