Получить цвет пикселя из данных растрового изображения в указанных координатах [x, y]

Я хочу получить цвет пикселя в растровых координатах, например:

[0,0] - пиксель в первой строке и первом столбце (вверху слева)

[0,1] - пиксель в первой строке и во втором столбце и т.д.

Я загружаю растровое изображение так:

BitsPerPixel = FileInfo[28];
width = FileInfo[18] + (FileInfo[19] << 8);
height = FileInfo[22] + (FileInfo[23] << 8);
int PixelsOffset = FileInfo[10] + (FileInfo[11] << 8);
int size = ((width * BitsPerPixel + 31) / 32) * 4 * height;
Pixels.resize(size);
hFile.seekg(PixelsOffset, ios::beg);
hFile.read(reinterpret_cast<char*>(Pixels.data()), size);
hFile.close();

и моя функция GetPixel:

void BITMAPLOADER::GetPixel(int x, int y, unsigned char* pixel_color)
{
    y = height - y;
    const int RowLength = 4 * ((width * BitsPerPixel + 31) / 32);
    pixel_color[0] = Pixels[RowLength * y * BitsPerPixel / 8 + x * BitsPerPixel / 8];
    pixel_color[1] = Pixels[RowLength * y * BitsPerPixel / 8 + x * BitsPerPixel / 8 + 1];
    pixel_color[2] = Pixels[RowLength * y * BitsPerPixel / 8 + x * BitsPerPixel / 8 + 2];
    pixel_color[3] = Pixels[RowLength * y * BitsPerPixel / 8 + x * BitsPerPixel / 8 + 3];
}

Я знаю, что данные в растровом изображении хранятся вверх ногами, поэтому я хотел инвертировать их с помощью y = height - y;, но с этой строкой я получаю только некоторые значения, которых даже нет в массиве данных изображения. Без инвертирования изображения я получаю некоторые значения, которые находятся в массиве, но они никогда не соответствуют заданным координатам. Мое растровое изображение может быть 24-битным или 32-битным.


person ProXicT    schedule 27.05.2015    source источник
comment
Должно быть height - 1 - y.   -  person rpress    schedule 27.05.2015
comment
Я тоже пробовал это, но он все еще возвращает неправильные значения.   -  person ProXicT    schedule 27.05.2015


Ответы (1)


Для битовой глубины = 24 сохраняется 3 байта. Заполнение выполняется не для каждого пикселя, а только для каждой строки:

const int bytesPerPixel = BitsPerPixel / 8;
const int align = 4;
const int RowLength = (width * bytesPerPixel + (align - 1)) & ~(align - 1);
...
pixel_color[0] = Pixels[RowLength * y + x * bytesPerPixel];
...
person rpress    schedule 27.05.2015
comment
Спасибо, прямо сейчас я хотел опубликовать решение, и я вижу ваш ответ :) Теперь он работает для меня со следующим кодом: pastebin.com /MYHVuvZq В любом случае спасибо за ответ! Не могли бы вы объяснить мне, пожалуйста, что делает это: (align - 1)) & ~(align - 1);? - person ProXicT; 27.05.2015
comment
@ProXicT Это старый прием округления до следующей степени двойки, если это необходимо. align должно быть степенью двойки. В этом случае нет необходимости в делении/сдвиге, операция И в сочетании с операцией НЕ очищает младшие биты. - person rpress; 27.05.2015
comment
О, спасибо, но я до сих пор не знаю, зачем это нужно. Почему бы вам просто не поставить 16 в инициализацию const? - person ProXicT; 27.05.2015