ペイントイベントで移動・回転・拡大するサンプルを作りました。
namespace PictureBox03;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// 画像
var fnt = new Font("", 48.0f);
var bmp = new Bitmap(768, 256);
using(var g = Graphics.FromImage(bmp))
{
g.Clear(Color.FromArgb(0, Color.AliceBlue));
g.DrawString("迷惑堂本舗", fnt, Brushes.Gray, 98.0f, 82.0f);
g.DrawString("迷惑堂本舗", fnt, Brushes.Black, 92.0f, 76.0f);
};
// カウンター
long counter = 0;
// ピクチャボックス
var picbox = new PictureBox
{
Dock = DockStyle.Fill,
Parent = this,
};
// ペイントイベント
picbox.Paint += (s, e) =>
{
var g = e.Graphics;
long i = counter % 360;
if (i > 0)
{
// リセット
g.ResetTransform();
// 移動
g.TranslateTransform(bmp.Width/2, bmp.Height/2);
// 拡大・縮小
float scale = 1.0f / (360.0f / (float)i);
g.ScaleTransform(scale, scale);
// 回転
g.RotateTransform(i);
// 移動(戻る)
g.TranslateTransform(bmp.Width/2*-1, bmp.Height/2*-1);
}
// 画像を描画
g.DrawImage(bmp, 0, 0);
};
// タイマーオブジェクトの生成と初期化
if (this.components == null) return;
var timer = new System.Windows.Forms.Timer(this.components)
{
Interval = 10,
};
// タイマーイベント
timer.Tick += (s, e) =>
{
// カウントアップ
counter++;
picbox.Invalidate();
};
// ロード
this.Load += (s, e) =>
{
timer.Start();
};
// クローズ
this.FormClosed += (s, e) =>
{
timer.Stop();
timer.Dispose();
};
}
}
雑記:
この記事のテーマとしては図形(文字列)を回転させるサンプルプログラムになります。
変換処理についてあまり理解が出来ていない状態です。
今のところの理解では、まずビットマップ自体が回転縮小するわけでは無く、ビットマップはキャンバスとして考えキャンバス内の画像を回転縮小しているようです。その際回転や移動などの中心点は左上(0,0)の座標らしく、そのまま回転すると左上を中心に回転します。ビットマップの中心で回転することを期待していたので、なぜそうなるか不思議に思いました。中心点が左上だとすると、中心点を図形の中心へ移動させて回転させればよいのではと思い試してみました。結果は予想通りですが今度は図形がビットマップの中心から移動してしまいます。というわけで先ほど移動した中心点を元に戻す処理をすることにしました。
ソースコードをぱっと見た感じ回転と拡大をしているだけなのに何故移動を挟むのか謎な感じがし、書いた等に人も期間を開けて見直すと何故こんなことをしているのかと疑問に思うことがあります。
雑記2:
図形が変換される動きアニメーションで表示するようにしています。タイマーを使って定期的にPictureBoxの再描画が発生するようにしているのですが、動きがぎこちない感じがします。描画のタイミングの時刻(前回の時刻との差)と、描画のパラメータ(前回と同じ数値で無いか?)と描画に要した時間などを計測してみれば原因が探れそうですが、筆者のスキルでは手に余る予感がします。
コメント