前置き
画像に署名(名前など)を入れたいとき、今までは画像編集ソフトを使用して行っていました。
しかし、画像に名前を入れるためだけのために画像編集ソフトを立ち上げるのが面倒だったので、簡単に名前を入れられるような仕組みが無いか考えました。
だったら2つの画像を合成すればいいのでは
そこで、インプット用の画像と署名用の画像を用意して、2つの画像を合成するプログラムを作成しました。
ざっくりとした仕様
input画像フォルダの中にあるpngファイルを抽出。
抽出したファイルに署名用ファイルを合成。
画像を操作するライブラリとしてPillowを採用。
インストールしていない場合は以下のコマンドでインストールしてください。
pip install Pillow
jsonファイルに以下を記載
- 署名用画像を張り付け位置(X座標、Y座標)
- 入力画像が格納されているパス
- 署名用画像のパス
- 合成した画像を出力する場所のパス
settings.json(記載例)
{
"X": 10,
"Y": 20,
"inputDir": "C:\\sample\\input\\",
"outputDir": "C:\\sampley\\output\\",
"overlay" : "C:\\Usample\\signature.png"
}
ソースコード
ImageOverlay.py
from PIL import Image
import json
import glob
import os
# 設定ファイル(.json)を読み込む関数
def load_settings(settings_path):
# エンコードを指定してあげないと文字化けする可能性がある。
with open(settings_path, 'r', encoding='utf-8') as file:
settings = json.load(file)
return settings
# 画像を合成する
def combine_images(main_image_path, overlay_image_path, output_image_path, settings):
# メイン画像とサブ画像を読み込む
main_image = Image.open(main_image_path)
overlay_image = Image.open(overlay_image_path)
# サブ画像を指定位置に重ねる
main_image.paste(overlay_image, (settings['X'], settings['Y']), overlay_image)
if os.path.exists(output_image_path):
os.remove(output_image_path)
# 合成結果を保存
main_image.save(output_image_path)
def main():
# 実行したPyファイルのパスを取得する。
script_file_path = os.path.abspath(__file__)
dir_path = os.path.dirname(script_file_path)
# 設定ファイルのパス
settings_path = dir_path + '\\settings.json'
print('settigs_path : ' + settings_path)
# 設定ファイルを読み込む
settings = load_settings(settings_path)
main_image_path = settings['inputDir'] + '*.png'
files = glob.glob(main_image_path)
# 出力先のパス
output_path = settings['outputDir']
print('output_path : ' + output_path)
# オーバーレイ
overlay_image_path = settings['overlay']
print('overlay_image_path : ' + overlay_image_path)
for file in files:
# ファイルパスからファイル名のみを取得
filename = os.path.basename(file)
output_image_path = output_path + filename
print('1:'+ output_image_path)
# 画像を合成
combine_images(file, overlay_image_path, output_image_path, settings)
if __name__ == "__main__":
main()
これで、画像に名前を入れるのがかなり楽になりました。