-1

I am trying to get all the pixels from a set image using LockBits and iterating through every pixel via for. But i am getting incorrect pixels. I exhilarate more in a second.

Code:

Bitmap bmp = new Bitmap(ImagePath);
pictureBox1.Image = bmp;
Rectangle bmpRec = new Rectangle(0, 0,
                                 bmp.Width, bmp.Height); // Creates Rectangle for holding picture
BitmapData bmpData = bmp.LockBits(bmpRec,
                                  ImageLockMode.ReadWrite,
                                  PixelFormat.Format32bppArgb); // Gets the Bitmap data
IntPtr Pointer = bmpData.Scan0; // Set pointer
int DataBytes = Math.Abs(bmpData.Stride) * bmp.Height; // Gets array size
byte[] rgbValues = new byte[DataBytes]; // Creates array
Marshal.Copy(Pointer, rgbValues, 0, DataBytes); // Copies of out memory

StringBuilder Pix = new StringBuilder(" ");

// pictureBox1.Image = bmp;
StringBuilder EachPixel = new StringBuilder("");

for (int i = 0; i < bmpData.Width; i++)
{
    for (int j = 0; j < bmpData.Height; j++)
    {
        var pixel = rgbValues[i + j * Math.Abs(bmpData.Stride)];
        Pix.Append(" ");
        Pix.Append(Color.FromArgb(pixel));
    }
}

Now I have created a 2x2 pixel image of pure blue. My output should be

255 0 0 255 255 0 0 255 255 0 0 255 255 0 0 255 (A R G B)

but i get something like

Color [A=0, R=0, G=0, B=255] Color [A=0, R=0, G=0, B=255] Color [A=0, R=0, G=0, B=0] Color [A=0, R=0, G=0, B=0]

Where am I going wrong? Sorry if I can't explain exactly whats wrong. Basically the pixel output is incorrect and doesn't match up with the input bmp.

rguarascia.ts
  • 694
  • 7
  • 19
  • One problem I can see is that you're reading rgbValues as an array of bytes and `var pixel` is a byte, yet Color.FromArgb takes an int as it's argument. – jaket May 08 '14 at 00:24
  • 1
    possible duplicate of http://stackoverflow.com/questions/13920428/net-getting-rgb-values-from-a-bitmap-using-lockbits – Richard Schneider May 08 '14 at 00:29
  • Not directly. And written in a different language. @RichardSchneider – rguarascia.ts May 08 '14 at 00:42
  • @Rynoh97: only the language is different, the core and the libraries are the same. Also remove the code that's not relevant to the question like the timer thing. – Cristian Ciupitu May 13 '14 at 02:00

2 Answers2

0

I'm not sure what exactly you're trying to do here... I think you misunderstand how Scan0 and Stride work. Scan0 is a pointer to the beginning of the image in memory. Stride is the length of each row in memory in bytes. You've already locked the image into memory with bmp.LockBits, you don't have to Marshal it.

Bitmap bmp = new Bitmap(ImagePath);
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
StringBuilder sb = new StringBuilder();

unsafe
{
    for (int y = 0; y < bmp.Height; y++)
    {
        byte* row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);
        for (int x = 0; x < bmp.Width; x++)
        {
            byte B = row[(x * 4)];
            byte G = row[(x * 4) + 1];
            byte R = row[(x * 4) + 2];
            byte A = row[(x * 4) + 3];
            sb.Append(String.Format("{0} {1} {2} {3} ", A, R, G, B);
        }
    }
}
eshs
  • 194
  • 7
0

Fixed the problem by changing what and how it outputs. I now use Color ARGB = Color.FromArgb(A, R, G, B) I also now use a pixel array.

byte B = row[(x * 4)];
byte G = row[(x * 4) + 1];
byte R = row[(x * 4) + 2];
byte A = row[(x * 4) + 3];
rguarascia.ts
  • 694
  • 7
  • 19