c# - 计算绘制的形状图像中的唯一像素

标签 c# algorithm graphics

我正在开发一个图形应用程序,用户可以在其中在 Canvas 上绘制任意数量的线(从点 A 到点 B 具有一定粗细)、矩形或椭圆。

完成后,我有一组形状数据,指示每个形状的位置和绘制的线条,我需要确定它们在研究项目中着色了多少个独特像素。

我天真的算法是为每个形状实现 bool shape.Contains(x,y) 并为图像中每个像素的每个绘制形状调用它以确定该像素是由直线、矩形还是椭圆绘制的。

换句话说,我可以创建 void shape.SetPixels(bool[,] canvas) 并将每个形状及其包含的每个像素设置为 true。这是我实际实现的,对于大数据集,速度慢得令人痛苦。

我觉得有一种更直接的方法可以从原始形状数据到我需要的输出,而无需检查每个像素。所以我的问题是,给定一组形状数据,是否有一个 O(n) 函数 bool[,] IsColored(int x, int y) {} 可以比任何一个都更直接地为彩色像素生成真/假矩阵我给出的想法?

最佳答案

避免使用 Bitmap.GetPixel 方法。它非常非常慢。如果可能,您可以使用 LockBits 或类似技术对位图数据进行低级访问。

在我的一个项目中我使用了:

public void LoadFromBitmap(Bitmap bmp)
    {
        if (bmp.Width != Width || bmp.Height != Height)
            throw new ArgumentException("Size missmatch");
        unsafe
        {
            BitmapData bmpData = null;
            try
            {
                bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

                for (int y = 0; y < bmpData.Height; y++)
                {
                    uint* p = (uint*)((byte*)bmpData.Scan0 + y * bmpData.Stride);
                    for (int x = 0; x < bmpData.Width; x++)
                    {
                        this[x, y] = RawColor.FromARGB(*p);
                        p++;
                    }
                }
            }
            finally
            {
                if (bmpData != null)
                    bmp.UnlockBits(bmpData);
            }
        }
    }

https://github.com/CodesInChaos/ChaosUtil/blob/master/Chaos.Image/Pixels.cs

另一个优化是为包含像素的数组实现一个池。根据我的经验,经常在大型对象堆上分配对象会给 gc 带来很大压力。

关于c# - 计算绘制的形状图像中的唯一像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7731199/

相关文章:

c# - 我可以依赖按注册顺序调用的事件处理程序吗?

c# - 查找 MongoDB 文档并仅匹配带有 C# 驱动程序的数组元素

algorithm - 堆排序的下界?

java - 如何使用图形库输出Java Applet?

r - ggplotify 包中的函数 as.ggplot() 出现奇怪的错误

c# - 变量什么时候成为闭包的一部分?

c# - 如何使用带进度条的 ASP.NET MVC4 Web Api 上传大文件

c++ - 如何执行高效的集合交集操作?

java - 二维数组的快速散列

java - 罗盘针绘制在错误的位置