ここでの答えは明らかにイエスです。GDI+ を使用すると、ビットマップ バッファーに直接描画するだけなので、以前の描画操作を元に戻したい場合は、次のいずれかを実行できます (問題の複雑さとパフォーマンスによって異なります)。
- ビットマップバッファで変更されたバイトを復元します
- 描画ビットマップの前の状態を再読み込みします
簡単な解決策は、2 つのビットマップを使用することです (このようなことは、通常、ダブル バッファリングと呼ばれます)。現在表示されているもの (および最終状態が含まれているもの) と、プレビューのみに使用されるものです。プレビュー 1 は、常に最初の 1 のコピーです - 現在の変更のみです。
この単純な実装の基本的なアルゴリズムは次のとおりです。
- 2 つのビットマップ (空白だが同じサイズ) [A と B という名前] から開始します。
- ユーザーが線を描く場合、常にビットマップ A のコピーを B に作成し、B に描画します - B を表示します
- ユーザーが行を終了したら、A に B のコピーを作成し、もう一度 B を表示します。
そのため、元のビットマップを変更しただけのプレビュー ビットマップを常に表示します。
C# でのプログラミング コードの例を次に示します (すべてのイベントが接続され、プレビュー ビットマップ B がピクチャ ボックス自体であると仮定します (ここでは、pictureBox1 という名前になっています)。
Bitmap bmp;
bool isDrawing;
Point previous;
void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isDrawing = true;
previous = e.Location;
}
void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isDrawing = false;
}
void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isDrawing)
{
using (Graphics g = Graphics.FromImage(bmp))
{
double wf = (double)bmp.Width / (double)pictureBox1.Width;
double hf = (double)bmp.Height / (double)pictureBox1.Height;
g.ScaleTransform((float)wf, (float)hf);
g.DrawLine(Pens.Black, e.Location, previous);
}
pictureBox1.Refresh();
previous = e.Location;
}
}
このコードは、マウスの左ボタンを押すだけで、ある点から別の点への直線の描画を表示するためにあらゆることを行います。