書いた人: lpre_ys
中の人がtktk時によく使っている、ImageMagickのコマンドについての解説ドキュメントです。
magic-potの為だけに入れるのは勿体ないツールなので、ぜひ使ってみてください。
以下のコマンドについてご質問等ございましたら、お気軽にどうぞ。
中の人は、WSLという、Windows上でLinux(Ubuntu)が動くヤツをつかって開発しています。
序盤の、1~2行で終わるコマンドの場合、Windowsでもコピペで動きますが、複数行にわたるコマンドは書き替えが必要になります。
書き替えが必要なコマンドに対しては、初回に限り、Windows版のコマンドも載せていますが、全てのコマンドには対応しておりません。
Windows版のコマンドが無い物については、ご自身で書き換えてご利用ください。
一部コマンドでは、中間画像を生成しています。
それらは邪魔なので、作業フォルダ直下にある、tmpフォルダに生成するようにしています。事前に用意しておいてください。
その他、必要とする画像は、全て作業フォルダ直下に置いてある想定です。
また、コマンドは全て、作業フォルダに入ってから実行しています。
こんな感じで、エフェクト用の連番画像が用意されていた場合、次のコマンドで、1発でツクール2k用のエフェクト画像に結合できる。
※パレットの並び替えは、ImageMaigckには無理なので、読み込み時に透明色を指定するなり、magic-potで一括変換するなりしてください。
エフェクト-in
magick montage v7_effect_* -geometry +0+0 -tile 5x png8:v7_effect.png
エフェクト-out
フォント周りのエラーが出ますが、無視して問題ありません。
-tile 5x で、入力画像を、横5枚で並べて結合、という指示。
右端、出力画像名の前のpng8:は、インデックスカラーPNGで保存、という意味です。
エフェクト同様、連番画像を用意しておけば、次の画像で合成可能。
magick montage face_* -geometry +0+0 -tile 4x4 -resize 192x face.png
顔グラの場合、減色は別ソフトでやるので、インデックスカラーの指定は行わない。
顔グラは、2倍 or 4倍のサイズで作画することが多いので、リサイズもこのタイミングで行っている。
-resize 192xで、横幅192に縦横比を保ってリサイズ、という指示。
あとは、別ソフトで減色しておわり。
こんな感じのエフェクト画像を、1コマずつバラしたい場合
エフェクト-out
magick v7_effect.png -crop 96x96 v7_effect.png
エフェクト-crop
-cropオプションの引数として、1コマの画像サイズを指定する。
ファイル名はには、自動的でハイフンと連番が付与される。
連番とファイル名の区切りを_にしたい、など、出力ファイル名のフォーマットを変える場合は下記のように、%dを使うと、そこに連番が入ったファイル名で生成される。
magick v7_effect.png -crop 96x96 v7_effect_crop_%d.png
エフェクト-crop2
歩行グラのように、縦横のサイズが違う画像も、もちろん可能
magick 歩行グラ.png -crop 24x32 output.png
-cropに限らず、ImageMagickのコマンドでは、縦横は「横x縦」という表記になります。
1コマずつ切り出した、下記のような画像元に
次のような、ツクールの「ピクチャの移動」で切り替わったように見せるため、縦長の画像を作るには。
※スペースの都合上、縦に縮めて表示しています。Chromeの場合、右クリック->新しいタブで画像を開く、とすると原寸表示できます。
magick mogrify -background '#00FF00' -gravity north -extent 100x240 revive-*.png
magick revive-*.png -append revive-v.png
※入力元画像を上書きします!
2つのコマンドにわけて実行しています。
100が画像の横幅です。
画像サイズに合わせて変更してください。
-gravity northが、余白生成時に、元画像をどの位置に置くかを表しています。
north(北)なので、上側。
この指定を忘れると、画像が中央になってしまいます。
先の例を、次のように、横長に作りたい場合
sprite-h
magick mogrify -background '#00FF00' -gravity west -extent 320x16 revive-*.png
magick revive-*.png +append revive-h.png
16が画像の縦幅です。
画像サイズに合わせて変更してください。
+append と、appendオプションを+にする事により、入力された複数の画像を、横に結合できます。
今回は、画像を左寄せにして余白を作りたいので、-gravity westを指定しています。
ここから、コマンドが複雑になるため、Windowsのコマンドプロンプトでは動作しなくなります。
初回のみ、Windows版のコマンドと、書き替えが必要な個所について説明を入れておきますので、以後、必要であればご自身で書き換えてご利用ください。
こんな感じの、シンプルに、黒で文字が書かれた画像を作るコマンド
テキスト1
フォントは、フリーフォントのPixelMplusの12ポイントの物を利用します。
※MSゴシックだとドットフォントの利用が上手く出来なかったので、似たような代替フォントで対応。
インストールは下記サイトからどうぞ。
http://itouhiro.hatenablog.com/entry/20130602/font
magick -size 200x200 xc:#00FF00 \
-font '/mnt/c/Windows/Fonts/PixelMplus12-Regular.ttf' -pointsize 12 +antialias \
-fill '#000000' -gravity north -annotate 0x0 'テスト文字\n改行はこう書くと出来る' \
-trim text1.png
magick -size 200x200 xc:#00FF00 ^
-font "c:/Windows/Fonts/PixelMplus12-Regular.ttf" -pointsize 12 +antialias ^
-fill "#000000" -gravity north -annotate 0x0 "テスト文字\n改行はこう書くと出来る" ^
-trim text1.png
Windows向けに書き換える場合、下記の対応が必要になります
\から^にする。'を"にする/mnt/c/で指定。WindowsならC:/になるフォント指定がポイント。
フルパスで指定しておけば、間違いなく動きます。 また、フォントに限らず、描画系は+antialiasで、アンチエイリアスをOFFにできます。
センタリングではなく、左寄せにしたい場合は、-gravity northを-gravity northwestに変えれば出来る。
こういう文字画像を作る
テキスト2
ツクールのシスグラを基に、下記のような画像を作っておく。色は使いたい色で。
文字色
このとき、画像の縦幅を13pxにしておくと、改行有のテキストでもいい感じになります。
違うフォントだったら、うまいこといい感じに調整してみてください。
magick -size 200x260 xc:#00FF00 \
-font '/mnt/c/Windows/Fonts/PixelMplus12-Regular.ttf' -pointsize 12 +antialias \
-fill '#1d1d1e' -gravity north -annotate 0x0+1+1 'テスト文字\n改行はこう書くと出来る' \
-fill 'textcolor.png' -gravity north -annotate 0x0 'テスト文字\n改行はこう書くと出来る' \
-trim text2.png
初期キャンバス(200x260)の大きさは、文字がはみ出ない程度の大きさなら何でもよい。
ただし、初期キャンバスの縦幅は、13(textcolor.pngの縦幅)の倍数にしておくこと。
そうしないと、グラデーションがずれる。
背景を、単色ではなく画像にする。
ツクールのウィンドウのように、繰り返し敷き詰めるタイプと、拡大表示するタイプの2種紹介。
背景画像にしたい画像を用意しておく
今回は、サンプルとしてこんな小さな画像を用意
背景1
magick -size 200x260 xc:transparent \
-font '/mnt/c/Windows/Fonts/PixelMplus12-Regular.ttf' -pointsize 12 +antialias \
-fill '#1d1d1e' -gravity north -annotate 0x0+1+1 'テスト文字\n改行はこう書くと出来る' \
-fill 'textcolor.png' -gravity north -annotate 0x0 'テスト文字\n改行はこう書くと出来る' \
-trim tmp/text.png
magick tmp/text.png -compose dst-over -size 200x260 tile:test-bg.png -composite text3-1.png
拡大版は、テキスト画像のサイズを把握しておく必要がある。
今回は、131x26になりました。
実際はシェルなりnode.jsなりで、画像サイズの取得も自動化して使っています。
magick -size 200x260 xc:transparent \
-font '/mnt/c/Windows/Fonts/PixelMplus12-Regular.ttf' -pointsize 12 +antialias \
-fill '#1d1d1e' -gravity north -annotate 0x0+1+1 'テスト文字\n改行はこう書くと出来る' \
-fill 'textcolor.png' -gravity north -annotate 0x0 'テスト文字\n改行はこう書くと出来る' \
-trim tmp/text.png
magick tmp/text.png -compose dst-over \( test-bg.png -resize 131x26! \) -composite text3-2.png
普通の画像に、ツクールのウィンドウみたいなボーダーを付ける。
今回は、"in.png"という名前で、下記のような画像を用意。
画像の縦横の大きさを調べておく。(今回の場合、150x100)
ボーダーin
出力結果は下記を目指す。
ボーダーout
ツクールのシスグラ(system.png)から、枠の部分(最上段、左から2番目)だけの画像を作り
さらにそこから、枠線以外を透過した画像を作っておく。
このとき、画像が入る部分は透明に、ツクール利用時に透過したい部分は、透過色(この例の場合真緑)にしておくのがポイント。
今回の場合、四角の1ドットはツクール利用時に透過させたいので、真緑にしています。
ボーダーsystem
画像ベースのフレーム(ボーダー)生成は、コマンド1発で出来ないので、1箇所ずつ地道に合成している。
magick system-border.png -repage 60x60+14+14 -crop 20x20 tmp/border.png
magick in.png \
\( tmp/border-1.png -resize 150x6! \) -gravity north -composite \
\( tmp/border-7.png -resize 150x6! \) -gravity south -composite \
\( tmp/border-3.png -resize 6x100! \) -gravity west -composite \
\( tmp/border-5.png -resize 6x100! \) -gravity east -composite \
tmp/border-0.png -gravity northwest -composite \
tmp/border-2.png -gravity northeast -composite \
tmp/border-6.png -gravity southwest -composite \
tmp/border-8.png -gravity southeast -composite \
out.png
ざっくり説明するとこんな感じ
いちいち縦横計算するの面倒なので、中の人は下記のようなシェルスクリプトを用意しておいて──
※実際に使っているスクリプトなので、ファイルパス等は上記とは変わっています
#!/bin/bash
TARGET=$1
set `magick identify -format '%[width] %[height]' ${TARGET}`
WIDTH=$1
HEIGHT=$2
magick system-border.png -repage 60x60+14+14 -crop 20x20 +repage tmp/border.png
magick -size ${WIDTH}x${HEIGHT} xc:#00FF00 \
-composite ${TARGET} -gravity center \
-composite \( tmp/border-1.png -resize ${WIDTH}x6! \) -gravity north \
-composite \( tmp/border-7.png -resize ${WIDTH}x6! \) -gravity south \
-composite \( tmp/border-3.png -resize 6x${HEIGHT}! \) -gravity west \
-composite \( tmp/border-5.png -resize 6x${HEIGHT}! \) -gravity east \
-composite tmp/border-0.png -gravity northwest \
-composite tmp/border-2.png -gravity northeast \
-composite tmp/border-6.png -gravity southwest \
-composite tmp/border-8.png -gravity southeast \
-composite ${TARGET}
下記のコマンド1発で、ボーダーが付くようにしてたりします。(上書き)
sh border.sh in.png
「画像に描画する」の項目をまとめて応用すると、ツクールのメッセージウィンドウ風のテキスト画像も、コマンドで生成できるようになります。
本編でよく使ってるコレとか、全部自動生成です。
メッセージ風
実際は、文字の内容は外部ファイルから入力したり、画像サイズはスクリプトで取得したりして、数十個まとめて一気に生成してます。
※上の例みたいな感じで、node.jsを使ったスクリプトが組んである。入力はyamlを使用。
今回の場合、テキストだけの画像が84x25になっていました。
最終的な画像サイズは、そこに余白分を足したサイズにしています。
magick -size 200x260 xc:transparent -font /mnt/c/Windows/Fonts/PixelMplus12-Regular.ttf -pointsize 12 +antialias \
-fill '#1d1d1e' -gravity north -annotate 0x0+1+1 'ホワイトハウス\n- 通用口 -' \
-fill textcolor.png -gravity north -annotate 0 'ホワイトハウス\n- 通用口 -' \
-trim tmp/text0.png
magick system-border.png -repage 60x60+14+14 -crop 20x20 +repage tmp/border.png
magick -size 108x37 xc:#00FF00 \( system-bg.png -resize 108x37! \) \
-composite tmp/text0.png -gravity center \
-composite \( tmp/border-1.png -resize 108x6! \) -gravity north \
-composite \( tmp/border-7.png -resize 108x6! \) -gravity south \
-composite \( tmp/border-3.png -resize 6x37! \) -gravity west \
-composite \( tmp/border-5.png -resize 6x37! \) -gravity east \
-composite tmp/border-0.png -gravity northwest \
-composite tmp/border-2.png -gravity northeast \
-composite tmp/border-6.png -gravity southwest \
-composite tmp/border-8.png -gravity southeast \
-composite text4.png
例えば、こういうグラデーションを使ったボタン画像があるとして。
※文字・透過色は後で合成する想定
ボタン1
下記コマンドで、赤いボタンを作ることが出来る。
magick button1.png -modulate 100,100,160 button1-1.png
ボタン1-1
-modulate 100,100,160の部分で、各種レタッチソフトの「色相・彩度・明度」をやっている。
ただし、順番は、"明度、彩度、色相"の順番。
今回は、色相だけ赤寄りにずらしている。
引数を変えれば、下記のように違う色にしたり、グレースケールにしたりもできる。
magick button1.png -modulate 100,100,50 button1-2.png
ボタン1-2
magick button1.png -modulate 100,0,100 button1-3.png
ボタン1-3
基本編で使ったボタン画像は、グラデーションの色相が統一されていたため、単純に色相をずらすだけでも、違和感無い画像が生成出来た。
ただし、下記のように、「明るい部分は黄色」「暗い部分を紫」に寄せたグラデーションの場合、色相をずらすだけでは意図した色味にならない。
ボタン2
例)基本編の最初のコマンドで、赤色・緑色に変更した画像
,
※わかりづらいが、光の色相も一緒にずれている
そこで、下記3つの画像を用意。
まず、ベース画像の色相のみを変更。
その後、各種レタッチソフトの「レイヤー合成」のように、合成モードを指定して重ね合わせることにより、どの色でも光が黄色く、影が紫に見えるような画像を生成する。
今回は、光を「オーバーレイ」、影を「乗算」で合成している。
magick button3.png -modulate 100,100,160 \
button3-l.png -compose overlay -composite \
button3-s.png -compose multiply -composite \
button3-1.png
ボタン3-1
基本編の緑ボタンと同じように、modulateの色相を50にずらした、緑ボタンはこんな感じ。
ボタン3-2
単色グラデ、複数色グラデ(色相ずらし)、複数色グラデ(合成モード利用)の3つを並べるとこんな感じ。
一番右が、一番自然に見えませんか?
主にイベントカットで利用する、ピクチャの色数を強引に増やす方法。
※色数が多く、かつ、綺麗に表示したいピクチャ向け。
イベントカットのように、複数の色をグラデーションで表現している場合、256色ではどうしても色数が足りず、解りやすいディザやノイズが出てしまう。
そこで、4枚のピクチャを重ね合わせる事により、疑似的に4倍の色数のピクチャ表示を行う手法。
以下、比較画像。左が256色、右が4倍の1024色の画像となる。
等倍ではわかりづらいが、帽子のあたりに顕著にディザが出ている。
下記のように、似た色ごとに4つにわけたピクチャを用意し、それぞれ透過ありで4枚同時に重ねて表示している。
※このゲーム内でも同じ画像を使ってます。
この画像生成に、ImageMagickを利用しています。
コマンドだけでは1発で終わらせられないので、分割して記載。
入力画像は、リサイズのみ終わっており、色自体はフルカラーの状態で用意(lr_top-base.png)
ベース画像
まずは、4色に減色した画像の生成。
magick lr_top-base.png +dither -colors 4 tmp/lr_top.png
4色
続いて、減色後の画像から、使用している色情報を取得
magick convert tmp/lr_top.png -format %c histogram:info:
コマンド実行結果
49279: ( 53, 88, 83) #355853 srgb(53,88,83)
8137: ( 60, 55, 73) #3C3749 srgb(60,55,73)
7814: (122,118,128) #7A7680 srgb(122,118,128)
11570: (198,189,180) #C6BDB4 srgb(198,189,180)
上記で取得したカラーコードを使って、画像の指定した色「以外」を削除するためのマスク画像を作成。
magick tmp/lr_top.png -fill transparent -opaque '#355853' matte:tmp/mask.matte
magick tmp/mask.matte -negate tmp/mask.png
マスク画像
元のフルカラー画像に、上記のマスク画像をもとに、ツクール上の透過色(真緑)を合成。
magick -size 320x240 xc:#00FF00 \( tmp/mask.png -alpha copy \) \
-alpha Set -composite -fill transparent -opaque '#FFFFFF' PNG32:tmp/tmp.png
magick lr_top-base.png tmp/tmp.png -composite lr_top-1.png
後は、残り3色に対しても同様の手順で画像を生成し、最後にお好きな減色ツールで減色すれば、4倍色用ピクチャの完成。
上記を基に、自動で4倍色用ピクチャを生成するシェルスクリプトは下記。
IN_DIRに入れた画像が、まとめて変換されるようになっている。
参考までにどうぞ。
リサイズと減色も面倒なので、このスクリプト上で行うようになっている。
#!/bin/bash
IN_DIR=4xcut/in/
OUT_DIR=4xcut/out/
RESIZED_DIR=4xcut/resized/
TMP_DIR=4xcut/tmp/
rm ${OUT_DIR}*.png ${RESIZED_DIR}*.png ${TMP_DIR}*.png
for img in ${IN_DIR}*.png; do
filename=`basename "${img}"`
magick ${img} -resize 320x -filter Lanczos2 -unsharp 0x0.75+0.5+0.25 ${RESIZED_DIR}${filename}
magick ${RESIZED_DIR}${filename} +dither -colors 4 ${TMP_DIR}${filename}
i=1
magick convert ${TMP_DIR}${filename} -format %c histogram:info: | while read -r line;
do
hex=`echo $line | sed -e "s/^[^#]*\(#......\).*$/\1/"`;
magick ${TMP_DIR}${filename} -fill transparent -opaque ${hex} matte:${TMP_DIR}mask.matte
magick ${TMP_DIR}mask.matte -negate ${TMP_DIR}mask.png
magick -size 320x240 xc:#00FF00 \( ${TMP_DIR}mask.png -alpha copy \) -alpha Set -composite -fill transparent -opaque '#FFFFFF' PNG32:${TMP_DIR}tmp.png
magick ${RESIZED_DIR}${filename} ${TMP_DIR}tmp.png -composite ${OUT_DIR}${filename%.*}-${i}.png
i=$((i + 1))
done;
done
pngquant 255 ${OUT_DIR}*.png --ext .png --force --speed=1
中の人が、tktkの時に使っているコマンドは、だいたい上記を応用したりなんやかんやしてる物になります。
とにかく強力なツールなので、ぜひ、使ってみてください。
私自身、ImageMagickは、毎度毎度ドキュメントを漁りながら、試行錯誤して使っている状況ですので、もっとシンプルな記述方法があったりするかもしれません。
あくまでも一例として、参考にしていただければ幸いです。
2020.5.某日 lpre_ys