您根本不需要渲染的 Canvas 或任何其他可见面板。
只需使用可视层中可用的基本绘图原语。
下面的DrawGeometry 方法将Geometry 绘制到BitmapSource 上,使用位图的渲染大小,即考虑其DPI 的大小,并返回生成的BitmapSource。
public static BitmapSource DrawGeometry(
BitmapSource source, Pen pen, Geometry geometry)
{
var visual = new DrawingVisual();
var rect = new Rect(0, 0, source.Width, source.Height);
using (var dc = visual.RenderOpen())
{
dc.DrawImage(source, rect);
dc.DrawGeometry(null, pen, geometry);
}
var target = new RenderTargetBitmap(
(int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Default);
target.Render(visual);
return target;
}
为了绘制位图的像素单元并因此忽略其 DPI,修改方法如下:
var rect = new Rect(0, 0, source.PixelWidth, source.PixelHeight);
using (var dc = visual.RenderOpen())
{
dc.DrawRectangle(new ImageBrush(source), null, rect);
dc.DrawGeometry(null, pen, geometry);
}
下面的方法使用上面的方法来绘制一条折线为IEnumerable<Point>。
public static BitmapSource DrawPolyline(
BitmapSource source, Pen pen, IEnumerable<Point> points)
{
var geometry = new PathGeometry();
if (points.Count() >= 2)
{
var figure = new PathFigure { StartPoint = points.First() };
figure.Segments.Add(new PolyLineSegment(points.Skip(1), true));
geometry.Figures.Add(figure);
}
return DrawGeometry(source, pen, geometry);
}
它会像这样使用
var source = new BitmapImage(new Uri(...));
var pen = new Pen
{
Brush = Brushes.Blue,
Thickness = 2,
};
var points = new List<Point>
{
new Point(100, 100),
new Point(1000, 100),
new Point(1000, 1000),
new Point(100, 1000),
new Point(100, 100),
};
image.Source = DrawPolyline(source, pen, points);