我正在开发一个图形应用程序,用户可以在其中在 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/