c# - 如何用颜色填充位图对象中的封闭区域

标签 c# graphics bitmap gdi

给区域内的点用颜色来填充区域,类似于油漆桶功能中的“绘图”。
这。 NET Framework,没有直接的等效项。
但我希望使用 C# 来做到这一点。
这可能吗?

最佳答案

这是一个非常简单的洪水填充算法,应该可以帮助您入门

void Form1_Paint(object sender, PaintEventArgs e)
{
    using (Bitmap bitmap = new Bitmap(500, 500))
    {
        using (Graphics g = Graphics.FromImage(bitmap))
        {
            g.Clear(Color.White);
            List<Point> points = new List<Point>();
            for (double i = 0; i < 10; i++)
            {
                double dist = (i % 2 == 0) ? 100 : 50;
                double x = 200 + Math.Cos(i / 10d * Math.PI * 2d) * dist;
                double y = 200 + Math.Sin(i / 10d * Math.PI * 2d) * dist;
                points.Add(new Point((int)x, (int)y));
            }
            g.DrawPolygon(Pens.Black, points.ToArray());
        }

        FloodFill(bitmap, 200, 200, Color.Red);

        e.Graphics.DrawImage(bitmap, 0, 0);
    }
}

void FloodFill(Bitmap bitmap, int x, int y, Color color)
{
    BitmapData data = bitmap.LockBits(
        new Rectangle(0, 0, bitmap.Width, bitmap.Height),
        ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
    int[] bits = new int[data.Stride / 4 * data.Height];
    Marshal.Copy(data.Scan0, bits, 0, bits.Length);

    LinkedList<Point> check = new LinkedList<Point>();
    int floodTo = color.ToArgb();
    int floodFrom = bits[x + y * data.Stride / 4];
    bits[x + y * data.Stride / 4] = floodTo;

    if (floodFrom != floodTo)
    {
        check.AddLast(new Point(x, y));
        while (check.Count > 0)
        {
            Point cur = check.First.Value;
            check.RemoveFirst();

            foreach (Point off in new Point[] {
                new Point(0, -1), new Point(0, 1), 
                new Point(-1, 0), new Point(1, 0)})
            {
                Point next = new Point(cur.X + off.X, cur.Y + off.Y);
                if (next.X >= 0 && next.Y >= 0 &&
                    next.X < data.Width &&
                    next.Y < data.Height)
                {
                    if (bits[next.X + next.Y * data.Stride / 4] == floodFrom)
                    {
                        check.AddLast(next);
                        bits[next.X + next.Y * data.Stride / 4] = floodTo;
                    }
                }
            }
        }
    }

    Marshal.Copy(bits, 0, data.Scan0, bits.Length);
    bitmap.UnlockBits(data);
}

关于c# - 如何用颜色填充位图对象中的封闭区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10038378/

相关文章:

c# - 检查对象列表中的所有属性是否相等

c# - 编译查询中的 EF.Functions.Like 无法转换为等效的 SQL

c# - 英语国家的 Windows Phone 本地化

java - 比较两个字符串并根据结果显示图像

c++ - 生成 GL_INVALID_VALUE 错误。无效的纹理尺寸。在 Cubemap 纹理上 427*240*6

android - 在 Canvas 上绘制文本不适用于可变位图

android - 如何高效地将 Android 位图转换为 Leptonica Pix?

c# - 当调用 AppDomain.CurrentDomain.AssemblyResolve 时,ResolveEventArgs.RequestingAssembly 为 null

Android相机 Intent : how to get full sized photo?

c++ - 在 gDebugger 中运行我的程序时出现奇怪的结果