撤消&重做gdi图形

时间:2015-02-25 19:45:18

标签: c# wpf gdi+ gdi undo

我试图在wpf中使用gdi实现撤消和重做。我对gdi不是很熟悉,我的尝试也没有成功。

在我的鼠标移动事件中,我画得像这样:

    using (var g = Gdi.Graphics.FromImage(tempBitmap))
    {
        g.SmoothingMode = Gdi.Drawing2D.SmoothingMode.AntiAlias;
        g.CompositingQuality = Gdi.Drawing2D.CompositingQuality.HighQuality;
        if (currentTool == "eraserBrush")
            g.CompositingMode = Gdi.Drawing2D.CompositingMode.SourceCopy;
        else
            g.CompositingMode = Gdi.Drawing2D.CompositingMode.SourceOver;
        g.DrawLine(pen,p0,p1);
    }

    // Copy GDI bitmap to WPF bitmap.
    var hbmp = tempBitmap.GetHbitmap();
    var options = BitmapSizeOptions.FromEmptyOptions();
    this.writableBmp.Source = Imaging.CreateBitmapSourceFromHBitmap(hbmp,
        IntPtr.Zero, Int32Rect.Empty, options);

    // Redraw the WPF Image control.
    this.writableBmp.InvalidateMeasure();
    this.writableBmp.InvalidateVisual();

tempBitmap是Gdi位图

在我的鼠标注册事件中,我将tempBitmap推送到堆栈,在我的撤销事件中,我从堆栈弹出并执行以下操作:

if (paintStack.Count <= 1)
                    return;

                paintStack.Pop();
                tempBitmap = paintStack.Peek();
 var hbmp = paintStack.Peek().GetHbitmap();
                var options = BitmapSizeOptions.FromEmptyOptions();
                this.writableBmp.Source = Imaging.CreateBitmapSourceFromHBitmap(hbmp,
                    IntPtr.Zero, Int32Rect.Empty, options);

                // Redraw the WPF Image control.
                this.writableBmp.InvalidateMeasure();
                this.writableBmp.InvalidateVisual();

但是点击撤消什么都不做。我相信我正在推送并将错误的项目弹出到堆栈中。我想我应该做gdi图形,而不是tempbitmap,但我不确定如何。

编辑:--------------------------------------------- -------

我采取了不同的方法,但它似乎是一个死胡同。我为行动历史创建了一个堆栈。在每次击打后将动作推到堆叠中,并在撤消后弹出。然后在我的撤消事件中,我只是重绘所有内容减去最后一个动作。如果我只是用gdi绘制线条和简单的东西,这可以正常工作。但是,我也有一个绘制图像的工具,以及很多图像。这种方法太慢了。 enter image description here 上面只展示了三个级别的撤消,我绘制得越多,撤消越慢(显然有更多动作从堆栈中读取并重绘)。

Theres必须通过拍摄当前画布的快照来实现这项工作。任何想法的家伙?

0 个答案:

没有答案