【问题标题】:How can I read the location of pixels from one particular colour?如何从一种特定颜色读取像素的位置?
【发布时间】:2014-02-11 17:29:57
【问题描述】:

我创建了一个只有黑白颜色的位图图像(白色背景,上面写着黑色字符)。我可以通过逐行扫描从整个图像中读取黑色像素(我的角色)和白色像素(背景)的总数。我的问题是如何将每个黑色像素的位置保存到一个数组中,并从这些黑色像素中随机将其中一半变为白色并保存新的位图图像。

【问题讨论】:

  • 您的位图是否开启了抗锯齿功能?我可以想象黑色和白色之间的值(由于插值模式)会使您的方法无效。

标签: c# image


【解决方案1】:

您可以使用以下代码行:

Bitmap myBitmap = new Bitmap("yourimage.jpg");
List<Point> BlackList = new List<Point>();
List<Point> WhileList = new List<Point>();

// Get the color of a pixel within myBitmap.
Color pixelColor = myBitmap.GetPixel(x, y);
if (pixelColor = Color.Black)
{
    //Add it to black pixel collection
    BlackList.Add(new Point(x,y));
}
else
{
    //Add it to white pixel collection
    WhiteList.Add(new Point(x,y));
}

您可以在此处设置一个 for 循环,逐个获取每个像素位置并将它们设置为您的黑白像素集合。而要存储位置,您可以使用泛型集合。

此外,stackoverflow 上的 this question 还将帮助您解决问题。

【讨论】:

  • jparthj,我知道,我的问题基本上是如何将黑色像素的新位置存储到新数组中?
【解决方案2】:

伪代码:

  1. 通过计算位图的宽度和高度来创建双 for 循环。如果我没记错的话,是image.Width/image.Height,或者image.X/image.Y

  2. 如果像素是黑色的,则将i-th 和j-th 索引作为您的坐标保存到黑色像素坐标的List 中。我建议使用一维字符串数组。

  3. 如果像素为白色,则将i-th 和j-th 索引保存为您的坐标,放入白色像素坐标的List

【讨论】:

  • 如果你来 Stackoverflow 找人帮你做作业,那你就来错地方了。请查看 SO 指南:stackoverflow.com/help
【解决方案3】:

以下是满足您需要的代码:

    public Image Process(Image image)
    {
        Random rnd = new Random();
        Bitmap b = new Bitmap(image);

        BitmapData bData = b.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, b.PixelFormat);

        int bitsPerPixel = Image.GetPixelFormatSize(bData.PixelFormat);

        /*the size of the image in bytes */
        int size = bData.Stride * bData.Height;

        /*Allocate buffer for image*/
        byte[] data = new byte[size];

        /*This overload copies data of /size/ into /data/ from location specified (/Scan0/)*/
        System.Runtime.InteropServices.Marshal.Copy(bData.Scan0, data, 0, size);

        for (int i = 0; i < size; i += bitsPerPixel / 8)
        {
            if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0)
            {
                var shouldChange = rnd.Next(0, 100) >= 50;

                if (shouldChange)
                {
                    data[i] = 255;
                    data[i + 1] = 255;
                    data[i + 2] = 255;
                }

            }
        }

        /* This override copies the data back into the location specified */
        System.Runtime.InteropServices.Marshal.Copy(data, 0, bData.Scan0, data.Length);

        b.UnlockBits(bData);

        return b;
    }

请注意,此代码使用 LockBits,因此它的执行速度明显快于使用 GetPixel/SetPixel 函数的代码。

【讨论】:

  • Kaspars Ozols,这看起来与我的问题不太相关。让我再重复一遍我的问题;我需要读取所有黑色像素的位置,然后随机将其中一半变为白色。
  • 这正是这段代码的作用。 if (data[i] == 0 &amp;&amp; data[i + 1] == 0 &amp;&amp; data[i + 2] == 0) 检查黑色像素,var shouldChange = rnd.Next(0, 100) &gt;= 50; 随机决定是否应更改像素,data[i] = 255;data[i + 1] = 255;data[i + 2] = 255; 将像素更改为白色。
  • @KasparsOzols 检查黑色像素后,如果我只想返回它们的像素坐标,我该怎么做?希望你能帮忙,谢谢。
猜你喜欢
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
  • 1970-01-01
  • 2012-06-07
  • 2012-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多