プログラム(もしくはPython)が初めての方を対象に、
- 簡単に作成できる画像サイズ変換ソフトの作成方法
をご紹介します。
本記事を読み終えたら、PC内に保存している画像を自由なサイズに縮小変換して、
- 空き容量を増やしたり、
- Lineで画像を送る際のデータ量を減らしたり
できるようになります。
本記事は、プログラムに触れた事が無い人を対象に、画像変換ソフト作成を通して、この世界の魅力に触れてみようという企画シリーズの1記事になります。
企画シリーズ全体は、下記の通りです。
Pythonを勉強しようかどうか、判断材料の1つにして頂ければ幸いです。
「プログラムを体験して楽しむ」企画
進め方ステップ
- 全体概要
- Pythonの導入方法(環境構築)
- Pythonの特徴と、どんな分野で使用されてる?
- 【Python入門者対象】最低限の文法紹介
- 【Python入門者対象】簡単な外部ライブラリ導入方法
- 【Python入門者対象】画像変換ソフトの作成・実行 ← 本記事
- 【Python入門者対象】お勧めの学習手順
作成するソフトの紹介(完成イメージ)
まずは全体把握のため、ソフトウェアの実行例を紹介します。
最初に任意のフォルダに、変換したい画像ファイルを入れておきます。
ソフトの特徴
- 指定したフォルダ内の画像が、全部変換される。
- 新規でフォルダが作成され、サイズ変換後の画像ファイルが保存される。(元画像はそのまま)
- 画像サイズは、コード上で任意のサイズに指定可能。
ソフトウェアのコード
コード全体を紹介した後に、各コードの詳細を解説をしていきます。
コード全体の紹介
コードの大きな流れは、以下の通りです。
- 使用するライブラリをimport で読み込む
- 変数に、「元画像が入ったフォルダパス」、「変換後の画像を保存するフォルダパス」、「変換後の画像サイズ」を代入する
- フォルダを新規作成(変換後の画像ファイル保存用)
- 変換前の画像から、1ファイルずつ、画像ファイルをコードに読込む
- ④で読み込んだ画像に対し、変換後サイズ(縦幅、横幅)を計算する
- 画像サイズを変換する
- 画像を、③で作ったフォルダに保存する
- ④〜⑦を、全画像で実行する
コード全体はこちらです。
import glob
import os
from PIL import Image
# 画像が保存されているフォルダパスを変数に代入
img_folder_path = '/Users/Shared/images/'
# 新規作成フォルダの名前を変数に代入
change_img_folder_path = img_folder_path + 'change/'
# サイズ変換後の画像サイズ (長辺側)を変数に代入
change_img_size = 320 # 320×320以下にする
# 新しいフォルダを作成
if not os.path.exists(change_img_folder_path):
os.mkdir(change_img_folder_path)
# フォルダ内の画像一覧を、パスで取得して変換、保存
image_file_path_list = glob.glob(img_folder_path + '*.jpg')
for image_file_path in image_file_path_list:
ori_img = Image.open(image_file_path)
ori_img_width = ori_img.width
ori_img_height = ori_img.height
# 画像サイズを縦横比の比率を保持するため、変換後の縦横サイズを計算
if ori_img_width >= ori_img_height:
change_img_width = change_img_size
change_img_height = int(ori_img_height * change_img_width
/ ori_img_width)
else:
change_img_height = change_img_size
change_img_width = int(ori_img_width * change_img_height
/ ori_img_height)
# 元ファイルと同じ名前で、指定したフォルダに変換した画像を保存
img_resize = ori_img.resize((change_img_width, change_img_height))
file_name = os.path.basename(image_file_path)
img_resize.save(change_img_folder_path + file_name)
コード全体を見て、「もう無理〜」と思われた方でも、大丈夫です!!
1つ1つは、それほど難しくないので、易しく解説していきます。
各コードの解説
①、使用するライブラリをimport で読み込む
import glob
import os
from PIL import Image
前の記事で既にご紹介した「pillow」ライブラリに加え、Python標準のライブラリ(最初から入っているライブラリ)、「glob」と「os」を読み込んでいます。
from PIL import Image という書き方に関して
- PIL というのが、外部ライブラリ「pillow」の本体です。
- そのPILには、色々な物が入っており、 その中のImageを使う、というイメージです。
「glob」と「os」は、後ほど、詳細をご説明します。
②、変数に、「元画像が入ったフォルダパス」、「変換後の画像を保存するフォルダパス」、「変換後の画像サイズ」を代入する
この部分の流れですが、
変数に以下の3つを代入していきます。
- 変換したい画像が入っている、フォルダへのパス
- 画像変換後、保存するフォルダへのパス
- 画像変換サイズ(縦と横のうち、長辺側)
# 画像が保存されているフォルダパスを変数に代入
img_folder_path = '/Users/Shared/images/'
# 新規作成する、フォルダの名前を変数に代入
change_img_folder_path = img_folder_path + 'change/'
# サイズ変換後の画像サイズ (長辺側)を変数に代入
change_img_size = 320 # 短辺側サイズは、比例して小さくする。(後程のコード)
今回は、フォルダ内に入っている画像ファイルを一括で変換するコードを作ります。
- 本コードでは、「change」というフォルダが新規作成され、その中にサイズ変換した画像を保存するという、挙動になっています。
上記コードの最終行は、サイズ変換後の画像サイズを代入しています。画像の縦、もしくは横の大きい側が、320pxになるようにします。
この「320」を他の値にすると、変換後の画像サイズ(長辺側)が、その値になります。
③、フォルダを新規作成(変換後の画像ファイル保存用)
ここでは,
- 変換後ファイルを保存するための、フォルダパスが存在しているかどうか確認する
- もし存在しなければ、フォルダを作成
の順番で実行しています。
# 新しいフォルダを作成
if not os.path.exists(change_img_folder_path):
os.mkdir(change_img_folder_path)
③-1 フォルダパスが存在しているかどうかの確認
冒頭のimportで読み込んだ、「os」モジュールを使用します。
os.path.exists(フォルダパス)で、指定したフォルダが存在するか、というコードになります。
os.path.exists() という表記で出てくる .(ドット)は、
- osというモジュールの中にある機能のうち、pathという機能があって、その中のexists()という機能を呼び出している
というイメージです。(より詳細は別記事でご紹介したいと思っています。)
not を文頭につけているので、このif文は、フォルダが存在しなければ条件が成立となります。
③-2 フォルダを作成
os.mkdir(フォルダパス)で、フォルダを新規作成できます。
④、変換前の画像から、1ファイルずつ、画像ファイルをコードに読込む
④-1 画像ファイルを配列で取得する。
ここでは、「glob」を使用しています。冒頭のimportで読む込んだモノです。
globというのは、パスを指定すると、その中身を配列で取得できるものです。
例えばあるフォルダのjpgファイルを全て取得したい場合、以下のコードを記述します。
image_file_path_list = glob.glob(img_folder_path + '*.jpg')
# *.jpg の * は、「どんな文字列でもOK」という意味です。
文字列が代入されている変数と 文字列の +(足し算)の意味ですが、例えば
- 変数「img_folder_path」に、’C:/Users/taro/Documents/images/’が代入
- それに 文字列「’*.jpg」 が + されると、
文字列連結をして、’C:/Users/taro/Documents/images/*.jpg’ になります。
変数「img_folder_path」が示すフォルダに、「test.jpg, test1.jpg, test3.jpg」の3つが存在する場合、
glob処理した結果、変数「image_file_path_list」には、下記配列が代入されます。
[‘/Users/Shared/images/test1.jpg’, /Users/Shared/images/test3.jpg’, ‘/Users/Shared/images/test.jpg’]
④-2 取得した配列から、1つずつ取得して、処理する。
for image_file_path in image_file_path_list:
前回の記事でも紹介した内容と重複しますが、
for 変数 in 配列 で、配列の中身(この場合、ファイルパス)を1つずつ変数「mage_file_path」に代入して、配列の最後まで、繰り返されます。
次に画像ファイルを読み込みます。
冒頭で読み込んだ「pillow」という外部ライブラリを使用します。
「pillow」を使えば、画像ファイルに様々な処理ができます。
導入に関しては、前記事でも紹介しているので、参考にしてみて下さい。
変数「image_file_path」に代入したファイルパスを、下記コードを使用してpillow形式で画像データを読込み、変数「ori_img」に代入しています。
ori_img = Image.open(image_file_path)
⑤、④で読み込んだ画像に対し、変換後サイズ(縦幅、横幅)を計算する
外部ライブラリ「pillow」を機能を使えば、読み込んだ画像サイズを取得できます。
横幅と縦幅(単位はPx)を、変数「ori_img_width」と「ori_img_height」に代入しています。
ori_img_width = ori_img.width
ori_img_height = ori_img.height
次に画像変換するサイズの計算になります。
画像サイズの縦と横の内、長辺側を320pxにして、短辺側は比例して縮小しています。
320pxというのは、コードの最初で、
- 「change_img_size = 320」
としているからです。
繰返しになりますが、このサイズを変更すると、任意の画像サイズに変更できます。
まずは画像の横幅が、縦幅より大きい場合のコードを記述しています。
if ori_img_width >= ori_img_height:
change_img_width = change_img_size
change_img_height = int(ori_img_height * change_img_width
/ ori_img_width)
ここでのポイントは、
- 画像の横幅を示す、変数「change_img_width」に、設定した320pxを代入。
- 画像の縦幅を示す変数「change_img_height」には、画像の縦横比を保ったまま縮小する計算をした後、その値を代入している。
- コード中の、int( )は、()の中身が小数点の時に整数に変換するものです。(例:int(3.9) → 3 のように、 切り捨て処理になります。)
次は、画像の縦幅が、横幅より大きい場合の処理です。
処理の考え方は同様です。
else:
change_img_height = change_img_size
change_img_width = int(ori_img_width * change_img_height
/ ori_img_height)
⑥、画像サイズを変換する
画像変換も、ライブラリ「pillow」を使えば、処理できます。
変数「ori_imag」は、読み込んだ元画像データ(pillow形式で)が入っています。
その変数の後に「. resize((横幅サイズ, 縦幅サイズ))」を記述する事で、画像変換処理が実施されます。
サイズ変換した画像データは、「img_resize」という変数に代入しています。
img_resize = ori_img.resize((change_img_width, change_img_height))
⑦、画像を、③で作ったフォルダに保存する
オリジナル画像の、ファイル名を取得
ここでは④-2で取得した、image_file_path を使用します。
まずはこのファイルパスが代入されている「image_file_path」から、フォルダ名を取得します。
ファイルパスから、フォルダパスの取得するとは?
- 例)ファイルパス C:/Users/taro/Documents/images/test.png
- → フォルダ名 test.png
のように、ファイルまでのパス情報を削除したものです。
冒頭で読み込んだライブラリ「os」を使用致します。
file_name = os.path.basename(image_file_path)
os.path.basename(ファイルパス文字列) を使用すれば、「ファイル名」が取得できます。
サイズ変換した画像データをファイルに保存
pillow形式の画像データが入っている変数「img_resize」の.save()を使用します。
img_resize.save(change_img_folder_path + file_name)
img_resize.save()のカッコの中には、保存するファイルパスを入れます。
上記コードの例の場合、 change_img_folder + file_name と変数の足し算になっています。
変数どうしの+(足し算)の意味ですが、例えば
- 変数「change_img_folder」に、’C:/Users/taro/Documents/images/’が入ってる。
- 変数「file_name」に、’test.png’がはいっていると
文字列連結をして、’C:/Users/taro/Documents/images/test.png’ になります。
⑧、④〜⑦を、全画像で実行する
④-2で記述したコード
for image_file_path in image_file_path_list:
で、配列の変数「image_file_path_list」の要素がなくなるまで、既に記述したコード(画像読込み→画像サイズ計算→保存)が繰返されます。
まとめ
本記事では、画像変換プログラムの作り方をご紹介しました。
いきなり色々なライブラリが出てきて、少し難しかったかもしれません。
ただ本企画では、プログラムの雰囲気を掴んで頂ければOKです。その上で、プログラムに興味が湧いたら、順次学習していけばいいと思います。
筆者も微力ながら、順次コンテンツを作っていきます。
画像フォルダに、数千個位の画像ファイルを入れて、順番に実行されていくのを見ていると、ちょっと「お〜」と思えるかもです(笑)
実行する際は、本ソフト上から新規で作成されるフォルダをすぐに開けば、順番にファイルが作られていくのが見えるので、お試し下さい。
雑談
こんなコードではなくて、GUIから操作したいよー
という方もいらっしゃると思います。
実はPythonを使用して、.exe形式(Windows)、.app形式(Mac)で起動する、GUIソフトを作る事が可能です。
ただ、今回の入門からは大きく逸脱してしまうので、本ブログのどこかで確実に紹介するように致します。
それでは次回、この企画の最終回になりますが、
- 「更なる学習に向けて」どうすればいいのかに関して
網羅的にご紹介できたらと思っています。
それでは、またです。