如何从一种特定颜色读取像素的位置?

时间:2014-02-11 17:29:57

标签: c# image

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

3 个答案:

答案 0 :(得分: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 还可以帮助您解决问题。

答案 1 :(得分:0)

的伪代码:

  1. 通过计算位图的宽度和高度来进行双循环。如果我没记错的话,那就是image.Width / image.Heightimage.X / image.Y

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

  3. 如果像素为白色,请将i - th和j - 索引作为坐标保存到List白色像素坐标中。

答案 2 :(得分:0)

以下代码将满足您的需求:

    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函数的代码执行速度更快。