揃っているのか、いないのか微妙な品揃えの PHP の GD Image 関数群。 その中にアフィン変換を行う imageaffine
が埋もれていました。半日苦労して攻略したので、メモを残しておきます。
affine 引数
リファレンスには 「0 から 5 までのキーを持つ配列。」 としか記述がありません。
まぁ行列の要素を並べた配列なんだろうなとは思うものの、並べかたが不明です。
これは、 imageaffinematrixget
を利用して、与えた引数と結果から逆算して、
$affine = [ $m00, $m01, $m10, $m11, $m02, $m12 ];
というマッピングのルールを割り出しました。
平行移動の補完
imageaffine
は、アフィン変換といいながら、平行移動関係はなにもしてくれないので、使用者側でなんとかする必要があります。
基本は、行列の $m02
, $m12
の平行移動成分を描画関数 (imagecopy
) 等の引数の描画位置に設定するのですが、実はそれだけだと微妙にずれた位置に描画されて絶望します。
単純に imageaffine
された画像をそのまま保存して表示させるとわかるのですが、imageaffine
は、回転とスケールした結果をトリミングして返すため、単に平行移動成分が無視されるだけでなく、画像の原点もずれることになります。
これを解決するには、画像の 4つの頂点座標に変換行列を適用した値を求め、結果からX座標の最小値 $minX
と、Y座標の最小値 $minY
を求めて、変換結果画像の原点が [ $minX, $minY ]
にくるように描画位置を補正てあげます。
これで、思った結果が得られるようになりました。