Python3 + ImageMagick
ImageMagick
画像処理を行う用事があり、それにこれを使うと良いと言われました。何かで見たことあると思ったらlatexをインストールした時についてきた気がする。使ったことなかったけど!
メリット
簡単に画像処理ができる!シェルコマンドでできる!つまりプログラミングと相性が良い!多分こんな感じです。
インストール
homebrewをインストールしていればこれで!
$ brew install imagemagick
Python + ImageMagick
基本
ImageMagickのコマンドをPythonの
subprocess.call(cmd, shell=True)
で実行させるだけです。
shell=Trueはsubprocessが行うコマンドをshell上で実行するというオプションなのですが、これが必要です。筆者はこれが必要であるということを調べるのに30分以上費やしました。cmdにコマンド文字列を作成していきます。
ImageMagickのコマンドは下記リンクを見て勉強しましたー!
サイズ変更
def changeSize(image, scale):
"""
画像のサイズを変更
縦横比は変えずにパーセンテージで指定
"""
cmd = "convert {} ".format(image)
o_resize = "-resize {}% ".format(scale)
o_out = "{}".format(image)
cmd = cmd + o_resize + o_out
res = subprocess.call(cmd, shell=True)
イメージとしてはこんな感じでやっていきます。
二つの画像の合成
def overlayImage(bottom_img, top_img, gravity="center", geometry=(5, 5)):
"""
2つの画像の合成
bottom_imgの上にtop_imgを乗せる
"""
cmd = "convert " + bottom_img + " " + top_img + " "
o_gravity = "-gravity {} ".format(gravity)
o_geometry = "-geometry +{0[0]}+{0[1]} ".format(geometry)
o_compose = "-compose over "
o_composite = "-composite {}".format(bottom_img)
cmd += o_gravity + o_geometry + o_compose + o_composite
res = subprocess.call(cmd, shell=True)
二つの画像を合成しています。gravityが基準点を決めるオプションで、geometryが基準点からの位置決めオプションです。めんどくさかったらgravity northwest にしておけばgeometryで左上からの位置を決められます。
ダミー画像生成
def makeBackground(name="muji", color="DodgerBlue"):
name = name + ".png"
res = subprocess.call("convert -size 1200x810 xc:white {}".format(name), shell=True)
このコマンドで無地のダミー画像が作れます。地味に使うこと多そう
ライン描画
def drawStroke(image, coords=(0, 0, 0, 0), color="black", width=1):
"""
幅と色指定のできる線描画関数
"""
cmd = "convert "
o_color = "-stroke {} ".format(color)
o_width = "-strokewidth {} ".format(width)
o_draw = '-draw "line {0[0]},{0[1]} {0[2]},{0[3]}" '.format(coords)
cmd = cmd + image + " " + o_color + o_width + o_draw + image
res = subprocess.call(cmd, shell=True)
これでラインが描けます。coordsで座標を決めていますが、
-draw "line (X1),(Y1) (X2),(Y2)"
の順で座標をとり2点間に直線を引きます。
図形は他にもいろいろあったけど、これしか使っていない。。
横並びに結合
def appendImage(img_list):
"""
画像を横並びに結合する
しばらく使わないので放置
"""
cmd = "convert +append "
for img in img_list:
in_file = "{}".format(i)
cmd += inFile + " "
cmd += "{}".format(img_list[0])
res = subprocess.call(cmd, shell=True)
forループ!!プログラミング使ってる感出てきた!(これで終わり説)
+append
で横並びの結合
-append
で縦並びの結合(らしい)
文字の挿入
def insertWords(image, words, color="black", font="Meiryo", size="50"):
"""
画像に文字を挿入
色とフォントと文字サイズの指定可能
挿入位置は画像下中央から10px上
"""
cmd = "convert "
o_point = "-pointsize {} ".format(size)
o_font = "-font {} ".format(font)
o_gravity = "-gravity south "
o_annotate = '-annotate +0+10 "{}" '.format(words)
o_fill = '-fill {} '.format(color)
o_in = "{} ".format(image)
o_out = "{}".format(image)
cmd = cmd + o_point + o_gravity + o_font + o_annotate + o_fill + o_in + o_out
res = subprocess.call(cmd, shell=True)
これは少し流派がありそうでした。label派とannotate派。先に見た方を選びました。
font-awesomeを使う
def makeFontAwesome(icon_name, color="black"):
"""
font awesome のunicodeから画像生成
色の指定可能
生成画像サイズは400x400
戻り値は画像の名前(相対パス名)
"""
icon = 'printf "{}" | '.format(icon_name)
cmd = "convert "
o_size = "-size 400x400 "
o_background = '-background "none" -fill {} '.format(color)
o_font = "-font font-awesome-4.7.0/fonts/fontawesome-webfont.ttf "
o_point = "-pointsize 200 "
o_gravity = "-gravity center label:@- "
o_out = "temp/{}.png".format(icon_name)
cmd = icon + cmd + o_size + o_background + o_font + o_point + o_gravity + o_out
res = subprocess.call(cmd, shell=True)
こいつはめちゃくちゃ苦労いたしました。基本的には下記リンク通り
とりあえずfont-awesomeのフォントをダウンロードしてきて、それを-fontで指定します。
font-awesome注意点
こいつを扱うときの注意点はズバリunicodeです。python3を使ってるから大丈夫と思っているみなさん、そんなこと言ってられなかった事案にぶち当たることもありました!何かと言うと、font-awesomeのunicodeを引数としてとってくる時に、標準入力などを用いると文字列がraw storingになっちゃうんですね。
\ufe03
これで地図の記号なのですが、標準入力まんま打ち込んでとってくるとpython上では
r"\ufe03"
という文字列になってしまいます。
何で困るって、この6文字で1文字を表すから画像表記できていたのに、6文字のまんま扱われたらfont-awesomeじゃないということです!(日本語が変)
これの解決策ですが、
fa = input() #r"\ufe03"
fa = fa.encode("utf-8") #b"\\ufe03"
fa = fa.decode("unicode-escape") #"\ufe03" → □
一回バイト列に変換してから、decodeのunicode-escapeとかいうやつでもう一回unicode文字列(raw string でない)に戻しました。絶対もっとうまい方法あると思うので知ってる方いたら教えてください。。
まとめ
ここに書いた関数群をモジュール化したらのちにも使えそうだなぁ〜(どうするのかさっぱりわからんし、そんなことするくらいならもっと他に画像編集できるライブラリありそう)