描いた絵に対してサインとして簡易URLのついたロゴを使っていて、それを自動で合成、それも色をなるべく浮かせないように合成するまでのあれこれ。
やり方が結構ズルズルしてるけど強引にワンライナに収められたので良しとします。
Debian 10 + ImageMagick(convert)
画像とか
base.pngJPGでもOK。アニメーションGIFはパッと見1コマ切り出すだけなのでサイン合成にはffmpegを使いましょう。
左上にロゴがついた。サインは見えづらいくらいが丁度いいとしても、ちょっと見えにくすぎるような…。
gravityオプションで比較的明るい右下にロゴを寄せる。
見やすくなったけども、ディテールがあって見どころでもある部分を隠してしまうのはちょっと…。
見やすくなったけども、ディテールがあって見どころでもある部分を隠してしまうのはちょっと…。
ちなみに
ロゴ画像を白黒2種準備して引数とかで適宜切り替えるという方法もあるけど省略。
gravityオプションについて
Northwest North Northeast
West Center East
Southwest South Southeast
平均色に変えてから合成させる
画像の平均色を取り出す
convertにピクセルの情報を出すオプションがあるそうなので、これを使う。
平均色といってもガシガシに縮小して縮こまったピクセルの色をもらってくるとかいう力技。
$ convert base.png -resize 3x3! -crop 1x1+2+2 -format "%[fx: r*255],%[fx: g * 255],%[fx: b*255]" info: | sed "s@\.@,@g" | awk -F"," '{print $1","$3","$5}'$ 66,55,36
- -resize 3x3! で画像をアスペクト無視(!をつける)で縦横3pxに縮小
- -crop 1x1+2+2 で左上から縦横2pxめの1pxに切り落とす(真ん中だけにする)
- -format "%[fx: r*255],%[fx: g * 255],%[fx: b*255]" info: でrgb値をカンマ区切りで出力
- 小数点以下を切り捨てるためにsedで「.」をカンマに変え、
awkでカンマを区切り文字にして1,3,5番目(小数点以上)を出力する
参考ページ探してたらもうちょい短い方法があった。
$ convert base.png -resize 3x3! -crop 1x1+2+2 txt: | tail -n1 | sed -e "s/.*srgb(//" -e "s/)$//g"$ 67,55,36
txt: 出力を使うと各ピクセルの色についてカラーコードなどと一緒に表示するらしい。ちょっとだけ前述のやり方と誤差がある。
コメントがついてしまうのでtailで切り、sedで丸カッコを外す。
コメントがついてしまうのでtailで切り、sedで丸カッコを外す。
平均色で塗ったレイヤcolor.pngを作成
いちいち変数に入れるのはアレなのでパイプしてxargsする。
$ convert base.png -resize 3x3! -crop 1x1+2+2 txt: | tail -n1 |sed -e "s/.*srgb(//" -e "s/)$//g" | xargs -I COLOR convert -size 300x300 xc:"rgb(COLOR)" color.png
黒地に金色の絵図だったのでまあ妥当。
参考:【 xargs 】コマンド――コマンドラインを作成して実行する
最高!
color.pngにsign.pngのアルファ値を適用
CopyOpacityを使う。
$ convert color.png sign.png -compose CopyOpacity -gravity southwest -composite signcolor.pngsigncolor.png
これまた分かりづらいけど300x300の透明画像の左下に色ロゴがついている。
絵に平均色ロゴを合成
最初に上げた合成と一緒。
_人人人人人人人人人人_
>真ん中寄りじゃねーか<
 ̄YYYYYYYYYY ̄
gravityをつけましょう。
$ convert base.png signcolor.png -gravity southwest -composite result.png
一括操作
これセミコロンで繋げてるだけでは………???
$ convert base.png -resize "3x3!" -crop 1x1+2+2 txt: | tail -n1 | sed -e "s/.*srgb(//" -e "s/)$//g" | xargs -I COLOR convert -size 300x300 xc:"rgb(COLOR)" color.png; convert color.png sign.png -compose CopyOpacity -gravity southwest -composite signcolor.png; convert base.png signcolor.png -gravity southwest -composite result.png; rm color.png signcolor.png
フォルダ内一括合成とか引数でロゴ位置とか考えてたけど眠いので終わります。
追記
シェルスクリプトにしました。引数にファイルパス、2番引数(任意)にImagemagickのGravity値を入れます。ロゴ画像の場所などは変数へ。
フォルダ内一括させたくてfor書いてるけど今のところフォルダ一括は無理です。ごめんね。
#!/bin/bash
# 自動で平均色をとって画像にサインロゴをはめ込むスクリプト
# -aでディレクトリ内全部、パス指定で1画像を、posに投げ込む
if [ "x$1" = "x" ]; then
echo "autosign [picture file path ] [position] "
exit
fi
cd $HOME
WMARK="$HOME/Pictures/wmark-autosign.png"
POSDIR="$HOME/Pictures/pos"
AVGCOLOR="$HOME/Pictures/avgcolor.png"
COLSIGN="$HOME/Pictures/colsign.png"
SOURCE="$1"
POS="southwest"
DEST=""
case "x$1" in
"-a" | "-A" ) SOURCE="ls -Q $PWD --color=never" ;;
* ) SOURCE="$1";;
esac
case "x$2" in
"x" ) POS="southwest" ;;
* ) POS="$2";;
esac
for i in $SOURCE ;do
DEST="$POSDIR/$(basename $i | sed s/...$/jpg/)"
echo "generating $DEST ..."
#入力から画像情報を取得、Tailで切りSedでRGB値のみに、Xargsで色サンプル画像を作る
convert $i -resize "3x3!" -crop 1x1+2+2 txt: |
tail -n1 |
sed -e "s/.*srgb(//" -e "s/)$//g" |
xargs -I COLOR convert -size 300x300 xc:"rgb(COLOR)" $AVGCOLOR
#色サンプル画像をロゴ画像で切り抜き
convert $AVGCOLOR sign.png -compose CopyOpacity -gravity $POS -composite $COLSIGN
convert $i $COLSIGN -gravity $POS -composite -quality 100 -interlace JPEG -comment "0xconfig.net" $DEST
rm $AVGCOLOR $COLSIGN
done
echo "Done."
0 件のコメント:
コメントを投稿