4

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);
            }
        }
    }
Madhawa Priyashantha
  • 9,633
  • 7
  • 33
  • 60
  • 2
    possible duplicate of [C# Image processing with lockbits, alternative to getpixel?](http://stackoverflow.com/questions/12168654/c-sharp-image-processing-with-lockbits-alternative-to-getpixel) – CodeCaster Oct 25 '13 at 09:52
  • 4
    Also, calling `TextBox.AppendText` a few ten thousand times is slow. Use a `StringBuilder`. – CodeCaster Oct 25 '13 at 09:53
  • 1
    Also, _"how we make a program like bar-code reader from image"_, don't reinvent the wheel: see [Recommend an Open Source .NET Barcode Reader Library](http://stackoverflow.com/questions/191192/recommend-an-open-source-net-barcode-reader-library). – CodeCaster Oct 25 '13 at 09:54
  • 1
    what did you mean by "reinvent the wheel"? – Madhawa Priyashantha Oct 25 '13 at 09:57
  • See [Don't Reinvent The Wheel, Unless You Plan on Learning More About Wheels](http://www.codinghorror.com/blog/2009/02/dont-reinvent-the-wheel-unless-you-plan-on-learning-more-about-wheels.html). – CodeCaster Oct 25 '13 at 09:59
  • 1
    codecaster ok i understand little.i will learn more... – Madhawa Priyashantha Oct 25 '13 at 12:30
  • 1
    It means: if your current assignment is to read barcodes from images and you currently don't know anything about images or barcodes, the quickest way to accomplish your goal is to use a (paid or free) third-party library that implements this. Alternatively, but that is usually only advisable when you are willing to understand all quirks of image recognition and barcode formats and you want to actually learn something from the exercise, then you can implement the whole shebang yourself, but it certainly will take more time while the results will at best be mediocre. – CodeCaster Oct 25 '13 at 12:34
  • 1
    ­­­­­­­­­­yes i think i need to use a library – Madhawa Priyashantha Oct 25 '13 at 13:23
  • You know, when looping over an image's x and y, the logical loop variable names are really just 'x' and 'y', not 'i' and 'z'... – Nyerguds Oct 19 '17 at 09:50

2 Answers2

3

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.

Alessandro D'Andria
  • 8,663
  • 2
  • 36
  • 32
1

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.

acfrancis
  • 3,569
  • 25
  • 21
  • 3
    `GetPixel` takes indeed long execution times. Using `LockBits` is the way to do this. – joe Oct 25 '13 at 09:58
  • I agree that ``LockBits`` is faster but in my experience, ``GetPixel`` doesn't take 20 minutes on a small image like that. What is he running this on? The original 4.77MHz IBM PC? – acfrancis Oct 25 '13 at 10:20
  • 1
    wait...exactly no my computer is (intel core 2 do ,4gb ram )computer and i try it on my core i5 ASUS laptop computer but problem is same ..really happaning thing is it exute at least 20 minutes and also get not responding ..and i trying different images some are big .i used image 704 width-1400 height it get not responding on both lap and pc check if you don't agree .i uplorded it http://www.mediafire.com/?7etr90i4hqkoa2q – Madhawa Priyashantha Oct 25 '13 at 12:44
  • 1
    It was a joke. Did you try any of the things I suggested? – acfrancis Oct 25 '13 at 13:19