CowBoy
CowBoy

Reputation: 195

How can I read the location of pixels from one particular colour?

I have created a bitmap image with only black and white colour (white background with black character written on it). I can read the total number of the black pixels (my character) and white pixels (background) from the entire image by scanning it line by line. My question is how I can save the location of each black pixel into an array and from those black pixels for example I turn half of them to white color randomly and save the new bitmap image.

Upvotes: 1

Views: 2111

Answers (3)

jparthj
jparthj

Reputation: 1636

you can use following line of code:

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));
}

here you can set a for loop that gets each pixel location one by one and set them to your black/white color pixel collection. And to store the location, you can use generic collection.

Moreover this question on stackoverflow will additionally help you solve your question.

Upvotes: 1

Kaspars Ozols
Kaspars Ozols

Reputation: 7017

Here is the code that will do what you need:

    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;
    }

Note that this code uses LockBits, so it will execute significally faster than code using GetPixel/SetPixel functions.

Upvotes: 0

theGreenCabbage
theGreenCabbage

Reputation: 4845

Pseudo-code:

  1. Make a double for-loop by calculating the width and height of your bitmap. If I remember correctly, it's image.Width/image.Height, or image.X/image.Y.

  2. If the pixel is black, save the i-th and j-th index as your coordinates, into the List of black pixel coordinates. I suggest a single-dimension string array.

  3. If the pixel is white, save that i-th and j-th index as your coordinates, into the List of white pixel coordinates.

Upvotes: 0

Related Questions