ImageMagick で黒帯背景に白文字を載せた画像を生成するシェル芸
よくタイトル画像やアイキャッチ画像で見かける “半透明な黒帯背景に白文字でタイトルが書いてあるあの画像” (なんて呼ぶのだろう?)を生成するシェル芸です。
できること
これが
これで
$ ./createImageWithText.sh tmp/src.jpg "ドラム式洗濯機はいいぞ\nめっちゃいいぞ\nm9(^Д^)プギャー" tmp/dst.jpg
こう!
ブログのアイキャッチ画像を簡単に生成するために作りました。
script
createImageWithText.sh
#!/bin/bash
set -e
usage="createImageWithText.sh src.jpg 'text' dst.jpg"
if [ ! $# -eq 3 ]; then
echo $usage
exit 1
fi
srcImage="$1"
text="$2"
dst="$3"
bgcolor='#0008'
echo "srcImage = $srcImage"
echo "text = $text"
echo "dst = $dst"
size=($(identify -format "%w %h" "$srcImage"))
srcW=${size[0]}
srcH=${size[1]}
echo "srcWidth = $srcW"
echo "srcHeight = $srcH"
bandW=$srcW
bandH=$(expr $srcH \* 3 / 7)
padW=$(expr $bandW / 8)
padH=$(expr $bandH / 6)
textW=$(expr $bandW - $padW \* 2)
textH=$(expr $bandH - $padH \* 2)
convert "$srcImage" \
\( \
-gravity center \
-size "${textW}x${textH}" \
-fill white \
-font ~/Library/Fonts/NotoSansCJKjp-Regular.otf \
-background $bgcolor \
label:"$text" \
-bordercolor $bgcolor \
-compose copy \
-border ${padW}x${padH} \
\) \
-gravity center \
-compose over \
-composite \
"$dst"
open "$dst"
ざっくり解説
ImageMagick を使用しています。
convert "$srcImage" \
\( \
-gravity center \
-size "${textW}x${textH}" \
-fill white \
-font ~/Library/Fonts/NotoSansCJKjp-Regular.otf \
-background $bgcolor \
label:"$text" \
-bordercolor $bgcolor \
-compose copy \
-border ${padW}x${padH} \
\) \
-gravity center \
-compose over \
-composite \
"$dst"
composite
オプションで $srcImage
と括弧内で錬成している “帯と文字部分” を重ねて $dst
に出力しています。
括弧内ですが、
-gravity center \
-size "${textW}x${textH}" \
-fill white \
-font ~/Library/Fonts/NotoSansCJKjp-Regular.otf \
-background $bgcolor \
label:"$text" \
の部分で黒背景の文を作成し、
-bordercolor $bgcolor \
-compose copy \
-border ${padW}x${padH} \
で padding 分を埋めています。
ImageMagick には extent
という領域を拡大するオプションがあるのですが、透過の background と組み合わせるとなぜか label で描画した部分の背景が extent
した部分に比べ濃くなってしまうため、背景色と同じ色の border
で囲って padding としました。
帯部分のサイズ計算がこちらです。
bandW=$srcW
bandH=$(expr $srcH \* 3 / 7)
padW=$(expr $bandW / 8)
padH=$(expr $bandH / 6)
textW=$(expr $bandW - $padW \* 2)
textH=$(expr $bandH - $padH \* 2)
計算内容は見ての通りなので解説は省略しますが、もし見ためが気に入らなければここを調節していただければサイズが変わります。
テキストの行数や長さに応じて可変にしてもよさそうですね。
以上
とりあえずのアイキャッチ画像としては及第点ではないでしょうか。
次は
- Hugo 向けに画像を最適化しつつ記事用ディレクトリに突っ込むスクリプト
- リサイズしてアイキャッチ画像を生成する wrapper スクリプト
を用意して Hugo でも画像周りでストレスの溜まらない環境を整備する予定です。
追記:
書きました