freedom-_-qの勉強履歴

メモ書きが主になるかと思います。勉強強制のために一日一記事目指してます。頭良くないので間違いが多々あるかと思います。

Pythonで画像結合と文字挿入

はじめに

会社で画像を結合と文字挿入する機会があった。
数ファイルであったら手動でいいが、40ファイル程度あったので手動では気が狂いそうなので、Pythonを使うことにする。
PythonにはPillow(PIL)という便利なモジュール群があるのでそれを利用する。

インポート

まずはそれらをインポートする。

from PIL import Image, ImageDraw, ImageFont
from pathlib import Path

画像結合(横)

基本の文法で結合する。
サンプルは「たしかなまんぞく」氏のきりたんを使用させてもらう。 img1, img2を横方向に結合する。
Image.new()で幅がimg1+img2Image.Imageインスタンスを生成して、そこにImage.Image.paste()で貼り付ける。

img1 = Image.open('001_通常(閉口).png')
img2 = Image.open('004_笑顔(閉口).png')
dst = Image.new(mode='RGB', size=(img1.width + img2.width, max(img1.height, img2.height)))
dst.paste(img1, box=(0, 0))
dst.paste(img2, box=(img1.width, 0))
dst.show()

f:id:freedom-_-q:20210608211826p:plain

このままでは結合するファイル数が増えると、変数が大変なことになってしまう。
そのため、Imagelistを受け取って結合後のImageを返す関数を作成する。
若干非効率な書き方かもしれないが以下で実現できる。

def concat_imgs(imgs:list)->Image:
    dst_width = sum([img.width for img in imgs])
    dst_height = max([img.height for img in imgs])
    dst = Image.new(mode='RGB', size=(dst_width, dst_height))
    loc = 0
    for img in imgs:
        dst.paste(img, (loc, 0))
        loc += img.width
    return dst

path = Path('.')
imgs = [Image.open(png) for png in path.glob('*.png')]
concat_imgs(imgs).show()

やばい(やばい)

f:id:freedom-_-q:20210608215303p:plain

hatenaの最大投稿可能画像ピクセルである10000px超えていたので、サイズ変更した。

画像結合(縦)

一部変更で縦結合にもできる。

def concat_imgs(imgs:list)->Image:
    dst_width = max([img.width for img in imgs]) #sum-->max
    dst_height = sum([img.height for img in imgs]) #max-->sum
    dst = Image.new(mode='RGB', size=(dst_width, dst_height))
    loc = 0
    for img in imgs:
        dst.paste(img, (0, loc)) #(loc, 0)-->(0, loc)
        loc += img.height #img.width-->img.height
    return dst

文字挿入

文字挿入はImage.Imageではなく、ImageDraw.Drawに対して操作する。

img1 = Image.open('001_通常(閉口).png')
draw = ImageDraw.Draw(img1)
font = ImageFont.truetype("arial.ttf", size=128)
draw.text(xy=(0,0), text='kiritan',font=font , fill='#F00')
img1.show()

f:id:freedom-_-q:20210608222600p:plain