WPF TileBrush和DrawingContext.DrawRectangle - 相对于矩形的左上角?

时间:2011-08-14 05:05:03

标签: c# wpf drawing brush drawingbrush

使用DrawingContextDrawRectangleTileBrush时,我注意到矩形的左上角不是底层图片的左上角。对于DrawingBrushImageBrush,源为DrawingImage时会发生这种情况。有没有办法强制DrawRectangle始终将底层画笔捕捉到左上角?这是一张图片:

An image of the brush alignment issues

两个矩形使用相同的画笔但位于屏幕上的不同点。正如您所看到的,画笔的原点是不同的(看起来画笔在更大的区域上是连续的)。这是一个最小的复制品:

    private static readonly Brush _brush;

    static CustomControl()
    {
        Uri uri = new Uri(@"pack://application:,,,/WpfApplication1;component/image.png", UriKind.Absolute);
        BitmapImage img = new BitmapImage(uri);
        Rect rect = new Rect(0, 0, img.Width, img.Height);
        ImageDrawing drawing = new ImageDrawing(img, rect);
        _brush = new DrawingBrush
        {
            Drawing = drawing, 
            Viewport = rect,
            ViewportUnits = BrushMappingMode.Absolute,
            TileMode = TileMode.Tile 
        };
        _brush.Freeze();
    }

    protected override void OnRender(DrawingContext dc)
    {
        dc.DrawRectangle(_brush, null, new Rect(70, 70, 100, 150));
        dc.DrawRectangle(_brush, null, new Rect(200, 200, 80, 120));
    }

*在这个的情况下,ImageBrush会给出正确的结果,但在我的程序中,我正在使用自定义GeometryDrawing处理DrawingBrush。

我尝试使用笔而不是刷子,更改TileMode,将拉伸设置为Uniform,更改AlignmentX和AlignmentY ......似乎没有任何效果。画笔的原点永远不会设置为矩形的原点。

2 个答案:

答案 0 :(得分:1)

根据我的经验,平铺画笔非常依赖于画笔的ViewboxViewboxUnitsViewportViewportUnits属性之间的关系。

单位的两个属性都应设置为Absolute; ViewportViewbox应该是相同的大小(99%的情况)。

详细说明,这不是我所读过的“官方”,它只是来自(很多)观察:Viewbox是用于渲染绘图的尺寸。如果未设置,则路径的Data将确定Viewbox大小。另一方面,Viewport是平铺画笔时考虑的尺寸。

Viewbox设置为小于Viewport的尺寸将在画笔的每个“图块”之间引入间距。将Viewbox设置为大于Viewport将导致'tile'重叠(逻辑上,在屏幕上'tile'似乎会被切割)。

答案 1 :(得分:1)

我使用的解决方案是使用TranslateTransform将其呈现在(0,0)。所以不是......

dc.DrawRectangle(_brush, null, new Rect(70, 70, 100, 150));

您可以使用:

TranslateTransform transform = new TranslateTransform(70, 70);
transform.Freeze();
dc.PushTransform(transform);
dc.DrawRectangle(_brush, null, new Rect(0, 0, 100, 150));
dc.Pop();

这并不理想,因为每次绘制一个新矩形时都必须分配一个新的TranslateTransform(以及另一个基础DUCE资源),但它在我的测试中表现良好。

重要提示:重新渲染时可能会遇到一些奇怪的(但微妙的)扭曲,例如滚动时。这些可能是由子像素渲染系统引起的。您可以使用GuidelineSet来游戏,也可以将起点的X和Y四舍五入到最接近的整数值。