几何尺寸与公差论坛

 找回密码
 注册
查看: 724|回复: 2

绘制几万个圆的效率问题

  [复制链接]
发表于 2023-3-21 17:30:20 | 显示全部楼层 |阅读模式
one draw issue without response using WPF, need draw about 50000~500000 circles(filled with white) into canvas, but it is drawing very slowly, sometimes windows 10 lost the response...
 楼主| 发表于 2023-3-21 17:31:11 | 显示全部楼层
One suggestion is to use a DrawingVisual instead of an Ellipse element, as it is a lightweight object that can be rendered faster1. You can create a custom class that inherits from DrawingVisual and override its OnRender method to draw circles using a DrawingContext1.

Another suggestion is to use a WriteableBitmap instead of a Canvas, as it allows you to manipulate pixels directly and avoid creating many UI elements2. You can use the WritePixels method to draw circles on the bitmap using an array of color values2.

A third suggestion is to use a StreamGeometry instead of an Ellipse element, as it is more efficient for complex shapes that do not need to be modified after they are created3. You can use the StreamGeometryContext class to define the geometry of the circles using arcs or beziers3.

I hope these suggestions are helpful for you. Please let me know if you have any questions or feedback.
 楼主| 发表于 2023-3-21 17:35:55 | 显示全部楼层
For the first suggestion, using a DrawingVisual, you can create a custom class like this:

public class CircleVisual : DrawingVisual
{
    public CircleVisual(double x, double y, double radius)
    {
        using (DrawingContext dc = RenderOpen())
        {
            dc.DrawEllipse(Brushes.White, new Pen(Brushes.White, 0.1), new Point(x,y), radius, radius);
        }
    }
}
Then you can add instances of this class to a VisualHost element in your XAML:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <VisualHost x:Name="visualHost"/>
    </Grid>
</Window>
And in your code-behind, you can loop through your data and create circles like this:

foreach (var item in DieControl.ThrdResultData.BumpHeighList.BumpHeight)
{
    CircleVisual circle = new CircleVisual(item.BumpPosX * scaleX, item.BumpPosY * scaleY, 25 * scaleX);
    visualHost.Children.Add(circle);
}
For the second suggestion, using a WriteableBitmap, you can create a bitmap and add it to an Image element in your XAML:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Image x:Name="image"/>
    </Grid>
</Window>
And in your code-behind, you can create a bitmap and draw circles on it using the WritePixels method:

WriteableBitmap bitmap = new WriteableBitmap((int)DieControl.MapCanvas.ActualWidth,
                                             (int)DieControl.MapCanvas.ActualHeight,
                                             96,
                                             96,
                                             PixelFormats.Bgra32,
                                             null);

for (int i = 0; i < DieControl.ThrdResultData.BumpHeighList.BumpHeight.Count; i++)
{
    int centerX = (int)(DieControl.ThrdResultData.BumpHeighList.BumpPosX[i] * scaleX);
    int centerY = (int)(DieControl.ThrdResultData.BumpHeighList.BumpPosY[i] * scaleY);
    int radius = (int)(25 * scaleX);

    // Create an array of color values for the circle pixels
    byte[] pixels = new byte[radius * radius * 4];
   
    // Fill the array with white color values
    for (int j = 0; j < pixels.Length; j += 4)
    {
        pixels[j] = 255; // blue
        pixels[j + 1] = 255; // green
        pixels[j + 2] = 255; // red
        pixels[j + 3] = 255; // alpha
    }

    // Write the pixels to the bitmap at the circle center position
    bitmap.WritePixels(new Int32Rect(centerX - radius / 2,
                                     centerY - radius / 2,
                                     radius,
                                     radius),
                       pixels,
                       radius * 4,
                       0);
}

// Set the image source to the bitmap
image.Source = bitmap;
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|几何尺寸与公差论坛

GMT+8, 2024-4-28 14:19 , Processed in 0.081614 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表