You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在SkiaSharp(WPF)中绘制大量圆形的高性能实现方案

高效绘制大量圆形散点的SkiaSharp优化方案

1. 用SKPaint.StrokeCap配合DrawPoints实现圆形点

DrawPoints的批量绘制性能远优于循环调用DrawCircle,只需设置笔触帽为圆形,就能让绘制的点呈现圆形效果:

var circlePaint = new SKPaint
{
    Color = SKColors.DarkOrange,
    StrokeWidth = 3, // 控制圆形直径
    StrokeCap = SKStrokeCap.Round // 核心设置:将点转为圆形
};
canvas.DrawPoints(SKPointMode.Points, visiblePointArray, circlePaint);

这种方式底层会批量处理顶点数据,性能比单循环DrawCircle提升数倍,完全适配5-20万级别的点量。

2. 视口裁剪过滤不可见点

由于支持缩放平移,无需绘制当前视口外的点。先根据当前变换矩阵计算可见区域,过滤掉不在区域内的点再绘制:

// 假设当前视口的可见范围为visibleRect
var filteredPoints = allStaticPoints.Where(p => visibleRect.Contains(p)).ToArray();
canvas.DrawPoints(SKPointMode.Points, filteredPoints, circlePaint);

缩放比例越高,可见点数量越少,性能提升越明显。

3. 静态数据预渲染离屏位图

针对静态数据,可提前将所有点渲染到离屏SKBitmap,后续缩放平移仅需绘制该位图(配合变换矩阵),无需重复绘制所有点:

// 初始化阶段完成预渲染
var offscreenBmp = new SKBitmap(canvasWidth, canvasHeight);
using (var offscreenCanvas = new SKCanvas(offscreenBmp))
{
    offscreenCanvas.DrawPoints(SKPointMode.Points, allStaticPoints, circlePaint);
}

// 后续交互绘制时
canvas.Save();
canvas.Translate(translateX, translateY);
canvas.Scale(scaleFactor);
canvas.DrawBitmap(offscreenBmp, 0, 0);
canvas.Restore();

注意:若圆形大小需随缩放动态变化,此方案不适用;若圆形大小固定,这是性能最优的实现方式。

4. 批量路径合并绘制(复杂场景备选)

如果需要带边框的圆形等复杂样式,可将所有圆形路径合并到一个SKPath中,一次性绘制:

var circlePath = new SKPath();
foreach (var point in filteredPoints)
{
    circlePath.AddCircle(point.X, point.Y, radius);
}
canvas.DrawPath(circlePath, circlePaint);

该方案性能弱于DrawPoints,仅适合特殊样式需求场景。

5. 低缩放级别降采样(可选优化)

在缩放比例较低、大量点重叠时,可对数据做降采样,比如每N个点取一个,或基于空间网格合并重叠点,减少绘制数量。


内容的提问来源于stack exchange,提问作者wforl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:33:25