Я использую WIC для загрузки изображения, а затем хочу получить значения RGB для каждого пикселя. Я дошел до использования getDataPointer () создать байт буфер (который я бросил в COLORREF массив) но после этого все становится странным.
У меня есть 10×10 24bit PNG, с которым я тестирую. Если я посмотрю на размер значение getDataPointer () дает мне сказать, что это 300, что имеет смысл, потому что 10 * 10 * 3 (для 3 байтов на пиксель) = 300. Если я getStride () это дает мне 30, что тоже имеет смысл.
Поэтому я создаю цикл, чтобы пройти через COLORREF с итератором и условие я < 3 Размер потому что я знаю, что в массиве всего 100 пикселей. Затем я использую макросы GetRValue (), GetGValue () а также GetBValue () чтобы получить значения RGB.
Это когда дела идут странно — мое маленькое изображение — это просто тестовое изображение с твердыми красными, зелеными, синими и черными пикселями, но мои значения RGB выходят (255, 0, 0), (0, 255, 0), ( 27, 255, 36), (0, 0, 0) и т. Д. Кажется, что некоторые значения не получаются должным образом и как-то искажены. Кроме того, последние 20/30 пикселей изображения — это либо сумасшедшие цвета, либо черные, что заставляет меня думать, что это какая-то порча.
Я также проверил это с более крупной реальной фотографией, и это выдает все оттенки серого и повторяет один и тот же образец, заставляя меня думать, что это — вопрос шага, но я не понимаю как, потому что, когда я звоню getPixelFormat () WIC говорит, что это 24bppBGR или 24bppRGB в зависимости от изображений.
Кто-нибудь знает, что я делаю не так? Разве я не должен использовать COLORREF и макросы или что-то подобное?
Спасибо за ваше время.
РЕДАКТИРОВАТЬ
Хм, у меня все еще есть проблема. Я попытался с другим 24-битным PNG, который PixelFormat () сообщал как 24bppBGR, но кажется, что шаг выключен или что-то в этом роде, потому что он рисует как перекошенный (обязательный тест nyan cat):
РЕДАКТИРОВАТЬ 2
Хорошо, теперь, кажется, у меня есть некоторые, которые работают, а некоторые нет. Некоторые сообщают, что они работают как 24bpp BGR, в то время как другие выглядят как на картинке выше, и если я вычислю шаг, это даст мне сравнение с тем, что должно быть, они отличаются, а также размер буфера также отличается. У меня также есть некоторые изображения BGR 32bpp, и некоторые из них работают, а другие нет. Я что-то здесь упускаю? Что может составить дополнительные байты в буфере?
Вот пример изображения:
24bppBGR JPEG:
width = 126
height = 79
buffer size = 30018
stride = 380
Если я вычислю это:
buffer size should be: width * height * 3 = 126 * 79 * 3 = 29862
difference between calculation and actual buffer size: 30018 - 29862 = 156 bytes
stride size should be: width * 3 = 378
difference between calculation and actual buffer size: 380 - 378 = 2 bytes
I was thinking that we had 2 extra bytes per line but 79 * 2 is 158 not 156 hmm.
Если я сделаю эти вычисления для изображений, которые работали до сих пор, я не найду никакой разницы в вычислениях и значениях, которые дает мне код …
Понимаю ли я, что здесь происходит неправильно? Должны ли эти расчеты работать так, как я думал?
еще раз спасибо
Вы не должны использовать COLORREF и связанные макросы. COLORREF — это 4-байтовый тип, и у вас есть 3-байтовые пиксели. Доступ к данным в виде массива значений COLORREF не будет работать. Вместо этого вы должны обращаться к нему как к массиву байтов с каждым пикселем, расположенным в ((x + y * width) * 3). Порядок отдельных каналов указывается названием формата. Так что если это 24bppBGR, вы бы сделали data [(x + y * width) * 3], чтобы получить синий канал, data [(x + y * width) * 3 + 1] для зеленого и data [(x + y) * ширина) * 3 + 2] для красного.
Если вам действительно нужен массив пикселей, вы можете создать структуру из 3 полей BYTE, но, поскольку значение этих полей зависит от формата пикселя, это может оказаться бесполезным.
На самом деле, вы не можете предполагать, что произвольное изображение будет загружаться как 24-битный формат вообще. Количество форматов, которые вы можете получить, больше, чем вы могли бы ожидать, чтобы поддерживать.
Вместо этого вы должны использовать WICConvertBitmapSource преобразовать данные в формат, с которым вы можете работать. Если вы предпочитаете работать с массивом COLORREF и связанными макросами, используйте GUID_WICPixelFormat32bppBGR.
Других решений пока нет …