Matrix.TransformPoints()でアフィン変換後の座標を計算してくれるようなので、試してみます。
プログラム
using System.Drawing.Drawing2D;
namespace MatrixSample;
public partial class Form1 : Form
{
Bitmap _bmp = new Bitmap(256, 256);
PictureBox picbox = new PictureBox
{
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.AutoSize,
};
// Matrixのプロパティを出力
static void OutputMatrix(Matrix mat)
{
Console.WriteLine("{0}", mat);
Console.Write("Elements:[");
foreach(var v in mat.Elements) {
Console.Write("{0:0.0},", v);
}
Console.WriteLine("]");
Console.WriteLine("IsIdentity:{0}",mat.IsIdentity);
Console.WriteLine("IsInvertible:{0}",mat.IsInvertible);
Console.WriteLine("OffsetX:{0}",mat.OffsetX);
Console.WriteLine("OffsetY:{0}",mat.OffsetY);
Console.WriteLine("");
}
public Form1()
{
InitializeComponent();
// 青色の画像
using (var g = Graphics.FromImage(_bmp))
{
g.Clear(Color.Blue);
}
// リサイズ
picbox.Resize += (s, e) =>
{
picbox.Image?.Dispose();
picbox.Image = new Bitmap(picbox.Width, picbox.Height);
};
// マウスクリック
picbox.MouseDown += (s, e) =>
{
if (picbox.Image is null) return;
using var g = Graphics.FromImage(picbox.Image);
// ピクチャボックスのクリア
g.Clear(picbox.BackColor);
// 領域
var rect = new RectangleF(-0.5f, -0.5f, _bmp.Width, _bmp.Height);
var points = new PointF[]
{
new PointF(rect.Left, rect.Top),
new PointF(rect.Right, rect.Top),
new PointF(rect.Left, rect.Bottom),
};
// 縮小、移動
var mat = new Matrix();
Console.WriteLine("Before");
OutputMatrix(mat);
mat.Scale(0.5f, 0.5f, MatrixOrder.Append);
mat.Translate(100, 100, MatrixOrder.Append);
Console.WriteLine("After");
OutputMatrix(mat);
mat.TransformPoints(points);
// 描画
g.DrawImage(
_bmp,
points,
rect,
GraphicsUnit.Pixel
);
Console.WriteLine("LT{0}, RT{1}, LB{2}", points[0], points[1], points[2]);
// リフレッシュ
picbox.Refresh();
};
this.Controls.Add(picbox);
}
}
結果
Before
System.Drawing.Drawing2D.Matrix
Elements:[1.0,0.0,0.0,1.0,0.0,0.0,]
IsIdentity:True
IsInvertible:True
OffsetX:0
OffsetY:0
After
System.Drawing.Drawing2D.Matrix
Elements:[0.5,0.0,0.0,0.5,100.0,100.0,]
IsIdentity:False
IsInvertible:True
OffsetX:100
OffsetY:100
LT{X=99.75, Y=99.75}, RT{X=227.75, Y=99.75}, LB{X=99.75, Y=227.75}
このプログラムでは高さ256幅256の青色の正方形のビットマップ画像を、アフィン変換で0.5倍に縮小し、x座標+100Y座標+100方向へ移動しています。移動後の座標を
TransformPoints()
で求めたの値は、99.75及び227.75の2種類になりました。例えば、LT(Left.Top)のXは99.75ですが、こちらは-0.5(x座標)*0.5(拡縮倍率)+100(x移動量)で求められます。
次にRT(Right.Top)のXは227.75ですが、こちらは(-0.5(x座標)+256(幅))*0.5(拡縮倍率)+100(x移動量)だと思われます。
PointFの配列を作る部分は少し面倒ですが、自前で計算することを考えると大変便利な機能だと思います。
コメント