这里的答案显然是肯定的。使用 GDI+,您只需直接在位图缓冲区上绘图,因此如果您想撤消先前的绘图操作,您可以执行以下操作之一(取决于问题的复杂性和性能):
- 恢复位图缓冲区上已更改的字节
- 重新加载绘图位图的先前状态
一个简单的解决方案是拥有 2 个位图(类似的东西通常称为双缓冲)。一个当前显示(并包含最终状态),一个仅用于预览。预览版始终是第一个的副本 - 只是带有当前修改。
所以这个简单实现的基本算法:
- 从两个位图开始(空白但大小相同)[命名为 A 和 B]
- 如果用户画一条线,总是在 B 中复制位图 A 并在 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;
}
}
这段代码将做所有事情来显示从一个点到另一个点的直线,只需按下鼠标左键。