Неправильный вывод пикселей

Я пытаюсь получить все пиксели из заданного изображения, используя LockBits, и повторяю каждый пиксель через for. Но я получаю неправильные пиксели. Я волнуюсь больше в секунду.

Код:

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

Теперь я создал изображение 2x2 пикселя чистого синего цвета. Мой вывод должен быть

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

но я получаю что-то вроде

Цвет [A=0, R=0, G=0, B=255] Цвет [A=0, R=0, G=0, B=255] Цвет [A=0, R=0, G=0, B=0] Цвет [A=0, R=0, G=0, B=0]

Где я ошибаюсь? Извините, если я не могу точно объяснить, что не так. В основном вывод пикселей неверен и не совпадает с входным bmp.


person Rynoh97    schedule 08.05.2014    source источник
comment
Одна проблема, которую я вижу, заключается в том, что вы читаете rgbValues ​​как массив байтов, а var pixel — это байт, а Color.FromArgb принимает int в качестве аргумента.   -  person jaket    schedule 08.05.2014
comment
возможный дубликат stackoverflow.com/questions/13920428/   -  person Richard Schneider    schedule 08.05.2014
comment
Не напрямую. И написано на другом языке. @РичардШнайдер   -  person Rynoh97    schedule 08.05.2014
comment
@Rynoh97: только язык другой, ядро ​​и библиотеки одинаковые. Также удалите код, который не имеет отношения к вопросу, например, таймер.   -  person Cristian Ciupitu    schedule 13.05.2014


Ответы (2)


Я не уверен, что именно вы пытаетесь здесь сделать... Я думаю, вы неправильно понимаете, как работают Scan0 и Stride. Scan0 — это указатель на начало изображения в памяти. Шаг — это длина каждой строки в памяти в байтах. Вы уже заблокировали образ в памяти с помощью bmp.LockBits, вам не нужно его маршалировать.

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);
        }
    }
}
person eshs    schedule 12.05.2014

Устранена проблема путем изменения того, что и как он выводит. Теперь я использую Color ARGB = Color.FromArgb(A, R, G, B) Я также теперь использую массив пикселей.

byte B = row[(x * 4)];
byte G = row[(x * 4) + 1];
byte R = row[(x * 4) + 2];
byte A = row[(x * 4) + 3];
person Rynoh97    schedule 13.05.2014