Pythonで利用できる画像ライブラリ[Pillow(PIL)]で画像に扁平させた文字を配置して電子印鑑(ハンコ)する手順を備忘録的に投稿しておきます。
Pillow(PIL)
Pythonで利用できるPillowは、画像に関する操作を行うライブラリで他のライブラリをインストールした際に、セットアップされている場合があります。
VSCodeの[ターミナル]画面などから次のコマンドで確認することができます。
pip show pillow
インストールされている場合にはバージョンなどの情報が表示されます。
インストールされていない場合には pip コマンドでインストールをしておきます。
pip install pillow
扁平させた文字を配置する手順
先回、文字を描画した画像をリサイズさせて扁平させた文字を取得する手順を紹介しましたが、この画像を配置して印面(ハンコ)のような画像を作っていきます。
実際にVSCodeを使って、扁平させた文字を配置するには次の手順で行います。
1. VSCodeを起動しプロジェクト用のフォルダーを内に[whiteback.py]ファイルを作成して次の関数を追加します。(後で使いやすいように関数化をしています)
from PIL import Image, ImageDraw, ImageFont
#扁平させた文字画像を作成
def flattext(moji, rasio):
base_W, base_H = (320,320)
#背景になる白画像を作成
image = Image.new('RGB', (base_W, base_H), 'white')
d = ImageDraw.Draw(image)
#書体を選択(サンプルではメイリオフォントを使用)
fontpath = "C:\Windows\Fonts\Meiryo.ttc"
font = ImageFont.truetype(fontpath, 200)
#描画後のサイズを事前に取得
moji_W, moji_H = d.textsize(moji, font=font)
#背景に文字を描画
d.text((0, 0 - (moji_H - moji_W)), moji, font=font, fill='red')
#出力したサイズで画像を切り抜き
image_crop = image.crop((0, 0, moji_W, moji_H))
#指定した数値(rasio)で画像をリサイズ
image_resize = image_crop.resize((moji_W, int(moji_H * rasio)))
return image_resize, (moji_W, int(moji_H * rasio))
#文字画像を配置する
def getimage(moji, yohaku):
base_W, base_H = (320,320)
#背景になる白画像を作成
base_image = Image.new('RGB', (base_W, base_H), 'white')
d = ImageDraw.Draw(base_image)
#扁平率(縦が70%)を設定
rasio = 0.7
#扁平させた文字画像を取得(1文字目)
image, (image_W, image_H) = flattext(moji[0], rasio)
#文字画像のサイズから背景になる白画像の上半分に配置
paste_W = int((base_W - image_W) / 2)
paste_H = int(((base_H / 2) - image_H) / 2) + yohaku
base_image.paste(image, (paste_W, paste_H))
#扁平させた文字画像を取得(2文字目)
image, (image_W, image_H) = flattext(moji[1], rasio)
#文字画像のサイズから背景になる白画像の下半分に配置
paste_W = int((base_W - image_W) / 2)
paste_H = int(((base_H / 2) - image_H) / 2) + int((base_H / 2)) - yohaku
base_image.paste(image, (paste_W, paste_H))
#背景になる白画像に赤い丸を描画
d.ellipse([(yohaku, yohaku), (base_W - yohaku, base_H - yohaku)], outline='red', width=6)
return base_image, (base_W, base_H)
2. 関数を呼び出すコードを[flattext.py]に追加します。
#画像に追加する余白
yohaku = 10
#扁平した文字と赤い丸を描画(getimage関数の呼び出し)
hanko_image, (base_W, base_H) = getimage('印鑑', yohaku)
#取得した画像をファイルに保存
hanko_image.save('C:\\Datas\\Python\\drawtext\\output\\hanko_image.png')
最終的に[whiteback.py]は次のようになります。
from PIL import Image, ImageDraw, ImageFont
def flattext(moji, rasio):
base_W, base_H = (320,320)
image = Image.new('RGB', (base_W, base_H), 'white')
d = ImageDraw.Draw(image)
fontpath = "C:\Windows\Fonts\Meiryo.ttc"
font = ImageFont.truetype(fontpath, 200)
moji_W, moji_H = d.textsize(moji, font=font)
d.text((0, 0 - (moji_H - moji_W)), moji, font=font, fill='red')
image_crop = image.crop((0, 0, moji_W, moji_H))
image_resize = image_crop.resize((moji_W, int(moji_H * rasio)))
return image_resize, (moji_W, int(moji_H * rasio))
def getimage(moji, yohaku):
base_W, base_H = (320,320)
base_image = Image.new('RGB', (base_W, base_H), 'white')
d = ImageDraw.Draw(base_image)
rasio = 0.7
image, (image_W, image_H) = flattext(moji[0], rasio)
paste_W = int((base_W - image_W) / 2)
paste_H = int(((base_H / 2) - image_H) / 2) + yohaku
base_image.paste(image, (paste_W, paste_H))
image, (image_W, image_H) = flattext(moji[1], rasio)
paste_W = int((base_W - image_W) / 2)
paste_H = int(((base_H / 2) - image_H) / 2) + int((base_H / 2)) - yohaku
base_image.paste(image, (paste_W, paste_H))
d.ellipse([(yohaku, yohaku), (base_W - yohaku, base_H - yohaku)], outline='red', width=6)
return base_image, (base_W, base_H)
yohaku = 10
hanko_image, (base_W, base_H) = getimage('印鑑', yohaku)
hanko_image.save('C:\\Datas\\Python\\drawtext\\output\\hanko_image.png')
3. 画像を保存するための[output]フォルダーを新しく作成します。
4. VSCodeの[ターミナル]画面で次のコマンドを実行します。
python whiteback.py
5.[output]フォルダーに画像が保存されます。
縦横比が変更された文字を描画させることができました。
このままでも、ハンコのように見えますが、印鑑の「鑑」の文字が赤い枠からはみ出しているのが分かります。この部分は「其の四」で修正していきます。
まとめ
Pythonで利用できる[Pillow]を利用して縦横比を変更した(横に伸ばした文字)を縦に並べて描画することで印面(ハンコ)のような画像を作成することができます。
今回は、横に伸ばした文字を赤い枠に配置することで多少はハンコのように見える画像を作ることができました。しかし画像をよく見てみると印鑑の「鑑」のような四角い形の漢字を使う場合に、赤い枠からはみ出してしまうことが分かりました。
次回は赤い枠からはみ出た部分と背景を透過にする手順を紹介していきます。
スポンサーリンク
最後までご覧いただき、ありがとうございます。