使用DrawingContext。DrawRectangle和TileBrush时,我注意到矩形的左上角不是底层图片的左上角。对于DrawingBrush和ImageBrush,源为DrawingImage时会发生这种情况。有没有办法强制DrawRectangle
始终将底层画笔捕捉到左上角?这是一张图片:
两个矩形使用相同的画笔但位于屏幕上的不同点。正如您所看到的,画笔的原点是不同的(看起来画笔在更大的区域上是连续的)。这是一个最小的复制品:
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 ......似乎没有任何效果。画笔的原点永远不会设置为矩形的原点。
答案 0 :(得分:1)
根据我的经验,平铺画笔非常依赖于画笔的Viewbox
,ViewboxUnits
,Viewport
和ViewportUnits
属性之间的关系。
单位的两个属性都应设置为Absolute
; Viewport
和Viewbox
应该是相同的大小(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四舍五入到最接近的整数值。