WPF自定义画布到位图重绘不正确

时间:2014-04-04 17:10:36

标签: wpf canvas

我已经实现了一个类似于WPF DrawTools(http://www.codeproject.com/Articles/22776/WPF-DrawTools)的自定义画布。我通过将画布转换为位图,执行泛光填充算法,然后将位图写回画布来实现泛光填充工具。

我遇到的问题是画布重绘不正确。画布相对于窗口保持在正确的位置,但画布中的绘图将根据偏移量移动。以下是执行转换的相关代码:

    public static WriteableBitmap GetBitmap(CCDrawingCanvas canvas) {
        // Local variables
        double dpi = 96d;

        // Get the size of the canvas
        System.Windows.Size size = new System.Windows.Size((int)canvas.ActualWidth, (int)canvas.ActualHeight);

        // Measure and arrange the surface
        Point relativePoint = canvas.TransformToAncestor(Application.Current.MainWindow)
                          .Transform(new Point(0, 0));
        canvas.Measure(size);
        canvas.Arrange(new Rect(size));

        RenderTargetBitmap source = new RenderTargetBitmap(
            (int)canvas.ActualWidth,
            (int)canvas.ActualHeight,
            dpi,
            dpi,
            PixelFormats.Pbgra32);
        canvas.RenderTransform = new TranslateTransform(relativePoint.X, relativePoint.Y);
        source.Render(canvas);

        return new WriteableBitmap(source);
    }

绘制第一条线时,画布和绘图将正确渲染。之后添加的每个新行都会将画布的每个子元素向下移动relativePoint.Y,然后移过relativePoint.X

如果我删除了relativePoint变换并返回WriteableBitmap,则画布将在相对于整个Window的位置(0,0)处绘制。这会通过重叠处于此位置的其他控制元素来导致问题。

我已经包含了两张图像,显示了绘制第一条线后的位置以及绘制第二条线后的位置。

在canvas元素的最顶部绘制的第一行。 First line drawn on the left 第二行是在画布的最顶部绘制的,但重绘会通过relativePoint.Y强制它 Second line drawn to the right

更新04/05/2014:我发现了一个临时解决方案。通过首先获取可视元素相对于窗口的位置,然后基于(0,0)位置排列画布来更改该过程。调用RenderTargetBitmap.Render()方法后,画布将相对于存储的点再次排列。这是更新的代码。我仍然想知道如何更优雅地执行此操作,因为此修复程序相当草率。

    public static WriteableBitmap GetBitmap(CCDrawingCanvas canvas) {
        // Local variables
        double dpi = 96d;

        // Get the size of the canvas
        System.Windows.Size size = new System.Windows.Size((int)canvas.ActualWidth, (int)canvas.ActualHeight);

        // Measure and arrange the surface based at a location of (0, 0) to write the bitmap properly
        canvas.Measure(size);
        Point relativePoint = canvas.TransformToAncestor(Application.Current.MainWindow)
                          .Transform(new Point(0, 0));
        canvas.Arrange(new Rect(size));

        RenderTargetBitmap source = new RenderTargetBitmap(
            (int)canvas.Width,
            (int)canvas.Height,
            dpi,
            dpi,
            PixelFormats.Pbgra32);
        source.Render(canvas);

        // Arrange the canvas back to its original position.
        canvas.Arrange(new Rect(relativePoint, size));

        return new WriteableBitmap(source);
    }

0 个答案:

没有答案