LoginSignup
0
1

More than 5 years have passed since last update.

Python 3 (v3.4.8) + ImageMagick > 複数画像を切出して合成する v0.1: ソース内の設定で動く | v0.2: JSONファイルから設定を読込む

Last updated at Posted at 2018-08-08
動作環境
CentOS release 6.9 (Final)
GNU Bash-4.1
ImageMagick Version: ImageMagick 6.7.2-7 2017-03-22 Q16
Python 3.4.8

関連

概要

  • 複数の画像ファイルを合成する
  • 切出し情報
    • srcPath: ファイルパス
    • cropSize: 切出しサイズ
    • srcLeftTop: 切出し左上座標
    • dstLeftTop: 合成先の左上座標

code v0.1

code

CONFIGSの設定を追加、削除することで、読込む画像数を変更可能。

composeImages_180808.py
import subprocess as sb
import sys

# v0.1 Aug. 8, 2018
#   - compose images based on the config dictionary

#on Python 3.4.8

CONFIGS = [
    {
        'srcPath': 'DIR1/out.png',
        'cropSize': '100x100',
        'srcLeftTop': '+10+10',
        'dstLeftTop': '+50+10'
    },
    {
        'srcPath': 'DIR2/out.png',
        'cropSize': '80x80',
        'srcLeftTop': '+10+10',
        'dstLeftTop': '+50+120'
    },
    {
        'srcPath': 'DIR3/out.png',
        'cropSize': '110x110',
        'srcLeftTop': '+30+30',
        'dstLeftTop': '+140+120'
    }
]

#convert -crop 100x200+50+40 Main.png 2.png
#  100:height, 200:width
#  50:left, 40:top

DSTFILE = "cmp.png"  # composed file (final output)

#1. make background
BGSIZE = "300x300"  # background image size
BGFILE = "back.png"  # background file
acmd = "convert -size %s xc:white %s" % (BGSIZE, BGFILE)
print(acmd)
sb.getoutput(acmd)  # instead of Popen() to wait the process to finish

for acfg in CONFIGS:
    print("-----")
    #2. crop image
    CROPFILE = 'crop.png'
    params = (acfg['cropSize'], acfg['srcLeftTop'], acfg['srcPath'], CROPFILE)
    acmd = "convert -crop %s%s %s %s" % params
    print(acmd)
    sb.getoutput(acmd)

    #3. compose
    params = "%s %s %s %s" % (acfg['dstLeftTop'], CROPFILE, BGFILE, DSTFILE)
    acmd = "composite -compose over -gravity northwest -geometry %s" % params
    print(acmd)
    sb.getoutput(acmd)

    #4. update background
    acmd = "cp %s %s" % (DSTFILE, BGFILE)
    print(acmd)
    sb.getoutput(acmd)

# message
print("-----")
print("[%s] is produced" % DSTFILE)

実行時環境

bash + ImageMagick > rainbow colorのボックスを作る v0.1
で作成したout.pngファイルを下記のように配置する。

  • DIR1/out.png
  • DIR2/out.png
  • DIR3/out.png

実行

run
$ python3 composeImages_180808.py 
convert -size 300x300 xc:white back.png
-----
convert -crop 100x100+10+10 DIR1/out.png crop.png
composite -compose over -gravity northwest -geometry +50+10 crop.png back.png cmp.png
cp cmp.png back.png
-----
convert -crop 80x80+10+10 DIR2/out.png crop.png
composite -compose over -gravity northwest -geometry +50+120 crop.png back.png cmp.png
cp cmp.png back.png
-----
convert -crop 110x110+30+30 DIR3/out.png crop.png
composite -compose over -gravity northwest -geometry +140+120 crop.png back.png cmp.png
cp cmp.png back.png
-----
[cmp.png] is produced

eog cmp.pngした結果は以下。

qiita.png

備考

subprocessの実行はPopen()でなくgetoutput()にした。
Popen()ではプロセスになり、処理が終わる前に後続の処理が実行される、という理解。

code v0.2

CONFIGURATIONをJSONファイルから読込むように変更

code

composeImages_180808.py
import subprocess as sb
import sys
import json

# v0.2 Aug. 8, 2018
#   - read CONFIGS from JSON file
# v0.1 Aug. 8, 2018
#   - compose images based on the config dictionary

#on Python 3.4.8

JSONFILE = 'config.json'

with open(JSONFILE) as reader:
    try:
        json_data = json.load(reader)
    except Exception as exc:
        print("Exception args:", exc.args)
        sys.exit()

#convert -crop 100x200+50+40 Main.png 2.png
#  100:height, 200:width
#  50:left, 40:top

DSTFILE = "cmp.png"  # composed file (final output)

#1. make background
BGSIZE = "300x300"  # background image size
BGFILE = "back.png"  # background file
acmd = "convert -size %s xc:white %s" % (BGSIZE, BGFILE)
print(acmd)
sb.getoutput(acmd)  # instead of Popen() to wait the process to finish

for images in json_data:
    for akey in images.keys():
        acfg = dict(images[akey])
        print("-----")
        #2. crop image
        CROPFILE = 'crop.png'
        prm = (acfg['cropSize'], acfg['srcLeftTop'], acfg['srcPath'], CROPFILE)
        acmd = "convert -crop %s%s %s %s" % prm
        print(acmd)
        sb.getoutput(acmd)

        #3. compose
        prm = "%s %s %s %s" % (acfg['dstLeftTop'], CROPFILE, BGFILE, DSTFILE)
        acmd = "composite -compose over -gravity northwest -geometry %s" % prm
        print(acmd)
        sb.getoutput(acmd)

        #4. update background
        acmd = "cp %s %s" % (DSTFILE, BGFILE)
        print(acmd)
        sb.getoutput(acmd)

# message
print("-----")
print("[%s] is produced" % DSTFILE)

JSONファイル

config.json
[
    {
        "image1": {
            "srcPath": "DIR1/out.png",
            "cropSize": "100x100",
            "srcLeftTop": "+10+10",
            "dstLeftTop": "+50+10"
        },
        "image2": {
            "srcPath": "DIR2/out.png",
            "cropSize": "80x80",
            "srcLeftTop": "+10+10",
            "dstLeftTop": "+50+120"
        },
        "image3": {
            "srcPath": "DIR3/out.png",
            "cropSize": "110x110",
            "srcLeftTop": "+30+30",
            "dstLeftTop": "+140+120"
        }
    }
]

実行

実行結果はv0.1と同じ。

v0.2 はまる点

  • JSONファイルのsrcPathに実在しないファイルパスを指定していると、処理の間違いに気づかない
  • JSONファイルの同じkey(例: image1)のセットが複数指定された場合、片方しか処理されない

関連

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1