Madhawa Priyashantha
Madhawa Priyashantha

Reputation: 9862

Get all pixel information of an image efficiently

I made a program to get all image pixel RGB color codes from picture. Basically, it sets y position on constant and changes x position zero to width and also y by looping.

Ok it's work, but the problem is it take more than 20 minutes to get all pixel from even (1000*604 height width) image. Please anyone help?

I'm surprised if this process takes so long, then how can we make a program like bar-code reader from image. I want to get all pixel value from image, here is my C# code are below.

I also uploaded my program here, check it if you don't agree.

    void myimage() {

        mypic = new Bitmap(pathname);
        int imwid = mypic.Width;
        int imhei = mypic.Height;
        int total=imwid*imhei;

        for (int z = 0; z <imhei;z++ )
        {
            for (int i = 0; i < imwid; i++)
            {
                Color pixelColor = mypic.GetPixel(i, z);

                textBox2.AppendText("  " + pixelColor.R + 
                    "     " + pixelColor.G + 
                    "     " + pixelColor.B + "     " + 
                    pixelColor.A + 
                    Environment.NewLine);
            }
        }
    }

Upvotes: 5

Views: 20906

Answers (2)

Alessandro D&#39;Andria
Alessandro D&#39;Andria

Reputation: 8868

Take a look at this:

var data = mypic.LockBits(
    new Rectangle(Point.Empty, mypic.Size),
    ImageLockMode.ReadWrite, mypic.PixelFormat);
var pixelSize = data.PixelFormat == PixelFormat.Format32bppArgb ? 4 : 3; // only works with 32 or 24 pixel-size bitmap!
var padding = data.Stride - (data.Width * pixelSize);
var bytes = new byte[data.Height * data.Stride];

// copy the bytes from bitmap to array
Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);

var index = 0;
var builder = new StringBuilder();

for (var y = 0; y < data.Height; y++)
{
    for (var x = 0; x < data.Width; x++)
    {
        Color pixelColor = Color.FromArgb(
            pixelSize == 3 ? 255 : bytes[index + 3], // A component if present
            bytes[index + 2], // R component
            bytes[index + 1], // G component
            bytes[index]      // B component
            );

        builder
            .Append("  ")
            .Append(pixelColor.R)
            .Append("     ")
            .Append(pixelColor.G)
            .Append("     ")
            .Append(pixelColor.B)
            .Append("     ")
            .Append(pixelColor.A)
            .AppendLine();

        index += pixelSize;
    }

    index += padding;
}

// copy back the bytes from array to the bitmap
Marshal.Copy(bytes, 0, data.Scan0, bytes.Length);

textBox2.Text = builder.ToString();

Is just an example, read some good tutorials about LockBits and imaging in general to understand clearly what happens.

Upvotes: 5

acfrancis
acfrancis

Reputation: 3661

Getting pixel information shouldn't take that long. Can you log the time it takes myimage() to run? The slowness might be somewhere else. Also try removing the line that begins with textBox2.AppendText in myimage() and see how fast it runs then.

Upvotes: 1

Related Questions