小学6年生の長男が夏休みの自由研究にPythonを勉強したいというので付き合ってみました。
どこから手を付けていけばわからないので、いくつか課題を出し、それを実現するコードを一緒に書くということを繰り返しました。
この記事では、「課題6 写真の整理」について扱います。その他の課題については下記の記事をご覧ください。
- 夏休みなので小学生とPythonを勉強してみた - 課題1 FizzBuzz - Qiita
- 夏休みなので小学生とPythonを勉強してみた - 課題2 掛け算九九 - Qiita
- 夏休みなので小学生とPythonを勉強してみた - 課題3 掛け算ゲーム - Qiita
- 夏休みなので小学生とPythonを勉強してみた - 課題4 じゃんけん - Qiita
- 夏休みなので小学生とPythonを勉強してみた - 課題5 サイコロの目の出る確率 - Qiita
- 夏休みなので小学生とPythonを勉強してみた - 課題7 掛け算ゲームWeb版 - Qiita
- 夏休みなので小学生とPythonを勉強してみた - 課題8 掲示板 - Qiita
- 夏休みなので小学生とPythonを勉強してみた - 課題9 顔の検出 - Qiita
- 夏休みなので小学生とPythonを勉強してみた - 課題10 顔の認識 - Qiita
コードはGitHubにて公開しています。
課題6-1 ファイル一覧
指示
カレント・ディレクトリ直下のsrcというディレクトリにある写真(JPEGファイル)の一覧を表示しましょう。
ヒント
globモジュールは、ディレクトリのワイルドカード検索からファイルのリストを生成するための関数を提供しています。
os.pathモジュールは、パス名を操作する便利な関数が実装されています。os.path.join関数はパスを結合します。
回答例
import glob
import os
SRC_PATH = 'src'
for image_file in glob.glob(os.path.join(SRC_PATH, '*.jpg')):
print(image_file)
課題6-2 ファイル名変更
指示
srcというディレクトリにある写真に連番で名前を付け、destというディレクトリにコピーしましょう。
ヒント
シーケンスにわたるループを行う際、enumerate関数を使うと、要素のインデックスと要素を同時に取り出すことができます。
shutilモジュールは、ファイルやファイルの集まりに対する高水準の操作方法を多数提供します。shutil.copyfile関数はファイルをコピーします。
回答例
import glob
import os
import shutil
SRC_PATH = 'src'
DEST_PATH = 'dest'
RENAME_FORMAT = 'image'
for i, image_file in enumerate(glob.glob(os.path.join(SRC_PATH, '*.jpg')), 1):
renamed_file = f'{RENAME_FORMAT}_{i:03}.jpg'
print(f'{os.path.basename(image_file)} -> {renamed_file}')
shutil.copy(image_file, os.path.join(DEST_PATH, renamed_file))
課題6-3 サムネイル作成
指示
srcというディレクトリにある写真に連番で名前を付け、destというディレクトリにコピーするとともにサムネイルを作成しましょう。
サムネイルは縦横それぞれ100ピクセル以内になるように作成します。
ヒント
画像を扱うライブラリはいろいろありますが、OpenCVを使うことにします。
画像ファイルを読み込むにはcv2.imread関数を使います。
画像の大きさはimg.shapeによって取得できます。縦ピクセル数、横ピクセル数、チャンネル数が返されるので、最初の2つを使います。
画像のサイズ変更は、cv2.resize関数を使います。
画像を保存するには、cv2.imwrite関数を使います。
回答例
import glob
import os
import shutil
import cv2
SRC_PATH = 'src'
DEST_PATH = 'dest'
RENAME_FORMAT = 'image'
THUMBNAIL_SIZE = 100
for i, image_file in enumerate(glob.glob(os.path.join(SRC_PATH, '*.jpg')), 1):
renamed_file = f'{RENAME_FORMAT}_{i:03}.jpg'
print(f'{os.path.basename(image_file)} -> {renamed_file}')
shutil.copy(image_file, os.path.join(DEST_PATH, renamed_file))
image = cv2.imread(image_file, cv2.IMREAD_COLOR)
height, width = image.shape[:2]
thumbnail_file = f'{RENAME_FORMAT}_{i:03}_thumb.jpg'
scale = min(THUMBNAIL_SIZE / height, THUMBNAIL_SIZE / width)
if scale < 1:
thumbnail_image = cv2.resize(image, dsize=None, fx=scale, fy=scale)
cv2.imwrite(
os.path.join(DEST_PATH, thumbnail_file),
thumbnail_image)
else:
shutil.copy(image_file, os.path.join(DEST_PATH, thumbnail_file))