サーバ側の画像処理は ImageMagickで大体乗り切れるはず その1

画像処理をAndroidやiPhoneなどのスマホ、PC側で行うのか、あるいはサーバ側で行うのかなど、サービスによっていろいろ検討することがあります。

うちでも、あるサービスは Fablic JS で構築し、別のサービスは ImageMagickで構築し、と使い分けています。

サーバ側の処理は Fablic JS + Node JS で行うこともできますし、PHP経由でImageMagicを使用することもできます。

例えばコンビニプリントサービスではフロントエンドではかなり簡単な jQueryベースで処理をし、サーバサイドで ImageMagick により画像を作成しています。

ImageMagicは一見ややこしそうですが、実はとてもシンプルに使えるため、多くのケースでImageMagickさえあれば画像の加工は乗り切れるのではないかと…さえ思えます。

ということで、簡単にですがImageMagickの処理を纏めてみましょう。

ざっくりいうと、ベースを作ってレイヤーを乗せていく感じ

convert -size 320x320 canvas:white output.jpg

これで 400px x 400px の白い画像キャンバスを作成し output.jpg という画像を作成しています。
これに画像を合成するとこうなります。

わかりやすくするために、1レイヤー1ブロックで区切るとこんな感じです。


convert -size 320x320 canvas:gray  \
 logo_145x145_b.png -composite       \
 output_001.jpg

グレーのキャンバスの上に画像を置きました。
行の後ろの \ は、改行をエスケープするだけですので、1行で書く時は不要です。

1行目で 320px × 320px でグレーのキャンバスを作成します。
2行目で logo_145x145_b.png という画像をその上に composite (合成)します。

さらにもう一枚画像を追加します。

convert -size 320x320 canvas:gray  \
 logo_145x145.png -composite        \
 circle.png        -composite        \
 output_002.jpg

こうなります。
後に書くほど上のレイヤーになります。

次はマークの位置を変更してみます。
キャンバスも白にします。

convert -size 320x320 canvas:white                     \
 logo_145x145_b.png  -geometry +87+87 -composite       \
 circle.png        -composite                          \
 output_003.jpg


こうなりますね。
geometoryオプションで位置を変更することができます。
この場合は、オフセットの起点が左上になっています。
センターを起点とする場合は -gravity center というオプションを追加します。

convert -size 320x320 canvas:white                     \
 logo_145x145_b.png  -geometry +87+87 -gravity center -composite       \
 circle.png        -composite                          \
 output_004.jpg

こうなります。
キャンバスの中心から、マーク画像の中心までのオフセットが 87px x 87px になりました。

ですので、次のようにすると元の位置に戻せます。

convert -size 320x320 canvas:white                     \
 logo_145x145_b.png  -geometry +0+0 -gravity center -composite       \
 circle.png        -composite                          \
 output_005.jpg

-gravity がセンターであれば、geometry オプションが0,0 のままでセンター合わせしてくれます。

ここまでで、【キャンバスを作る】→【下のレイヤーから順に貼っていく】→【レイヤーごとにエフェクトを入れられる】という事が分かったかと思います。

次は、最も便利な distort オプションについて解説します。

distort SRT 最強説

convert のオプションに distort があります。distortion (ゆがみ)の省略形で SRTは Scale-Rotate-Translate (拡縮、回転、移す)の省略形です。

回転させるとこんな感じです。

convert -size 320x320 canvas:white                     \
 logo_145x145_b.png  -gravity center  -distort SRT '10' -composite       \
 circle.png        -composite                          \
 output_011.jpg

-distort SRT に続いて 1つだけ値を指定していますが、それが回転を表しています。
値の組み合わせは下記の様に7種類あります。

基準位置スケール回転新しい位置備考
1Angle回転
2ScaleAngleスケールと回転
3X,YAngle 基準位置と回転
4X,YScaleAngle 基準位置とスケールと回転
5X,YScaleX,ScaleYAngle 基準位置と縦縮尺・横縮尺と回転
6X,YScaleAngleNewX,NewY 基準位置と縮尺と回転と
7X,Y ScaleX,ScaleY Angle NewX,NewY

2の引数2つでスケールと回転を指定してみます。

convert -size 320x320 canvas:white                     \
 logo_145x145_b.png  -gravity center  -distort SRT '1.5 10' -composite       \
 circle.png        -composite                          \
 output_012.jpg

こうなります。

拡大と回転が適用されました。

隙間を埋める

回転だけさせた画像では、回転して現れたエリアには画像の枠を引きずったような色がついていました。また拡大して回転させた画像は、周囲が切れたようになっていました。
これは元の画像のエリア内(バウンディングボックス内)で処理されるために起こります。

convert -size 320x320 canvas:white                     \
 logo_145x145_b.png  -gravity center  -distort SRT '10' -vertual-pixcel transparent -composite       \
 circle.png        -composite                          \
 output_013.jpg

-vertual-pixel transparent (透明) を指定するとこのようになり、余計な軌跡のようなエリアは消えました。

実は distort には – と + がある

上の例では余計なエリアは消せましたが、角々が消える、バウンディングボックス内のみ描画されることは変わりません。これを、元の画像をはみ出て描画されるようにしてみましょう。

convert -size 320x320 canvas:white                     \
 logo_145x145_b.png  -gravity center -virtual-pixel transparent +distort SRT '10'  -composite       \
 circle.png        -composite                          \
 output_014.jpg

こうすると、こうなります。

canvas 自体も回転してしまっています。
そこで、影響範囲をブロックで区切ります。

convert -size 320x320 canvas:white                     \
 \( logo_145x145_b.png  -gravity center -virtual-pixel transparent +distort SRT '10' \) -composite       \
 circle.png        -composite                          \
 output_015.jpg

画像 logo_145x145_b.png のみに適用するように、エフェクトを掛ける範囲をカッコ()で区切ります。そのカッコの範囲内で処理したものを -composite で合成する感じです。

拡大したロゴも +distort してみましょう。

convert -size 320x320 canvas:white                     \
 \( logo_145x145_b.png  -gravity center -virtual-pixel transparent +distort SRT '1.5 10' \)  -composite  \
 circle.png        -composite                          \
 output_016.jpg

こうなります。

元画像をはみ出さずに処理する -distort と はみ出して処理される +distort がありますので、目的に合わせて使い分けると思った通りの処理が出来ます。

ただ、+distort ですと基準位置のオフセットなどが思う通りにならない場合があります。
このあたりはまた調べてから記載します。

余談ですが、ImageMagickは magic ではなく magickなんですね。今まで意識したことがありませんでした。

コメント

タイトルとURLをコピーしました