пиксель, не выровненный по двойному слову, в растровое изображение с выравниванием по двойному слову

Мне нужно преобразовать необработанные пиксельные данные (строки * col = 479 * 638), которые не выровнены по DWORD, в растровые данные с выравниванием по DWORD. У меня мало сомнений.

1) Когда я говорю, что d выровнено по слову, речь идет о выделении общей памяти, выровненной по двойному слову, или о выравнивании ширины по DWORD?

2) Скажем, если речь идет о том, чтобы фактическая ширина была выровнена по DWORD, то из-за выравнивания по DWORD я добавляю дополнительные 2 байта в конце, чтобы сделать ширину = 640. но когда я делаю memcopy из источника в пункт назначения, он оставляет темно-черный линия внизу. Но мне не нужны эти темные линии, так как они создают путаницу с реальным изображением. Итак, как я могу избежать этой черной линии в конце?

Чтобы решить эту проблему, я предположил, что речь идет об общей выделенной памяти, которая выровнена по двойному слову. И я выделил столько памяти, выровненной по двойному слову.

bitmapData = (LPBYTE) GlobalAlloc(GMEM_FIXED, bmiHeader->biSizeImage);

Где bmiHeader->biSizeImage = nrows * dowrdalignedwidth * BPP.

Выполняя настоящую memcopy, я копирую и записываю в rows*cols*BPP. Это правильно?


person GAP    schedule 04.02.2013    source источник
comment
Подождите, вы сначала спрашиваете, как преобразовать данные в формат, выровненный по DWORD (что бы это ни было), а затем, что такое формат, выровненный по DWORD?   -  person Bartek Banachewicz    schedule 04.02.2013
comment
Если вы говорите о формате изображения, скорее всего, некоторые элементы или их расположение (абсолютное, от начала файла или относительно других элементов) должны быть кратны чему-то, и это практически не имеет отношения к тому, является ли или не те же самые элементы встречаются в каким-то образом выровненных местах в памяти.   -  person Alexey Frunze    schedule 04.02.2013
comment
Какой у вас формат пикселей, т.е. сколько бит на пиксель?   -  person Nanhydrin    schedule 04.02.2013
comment
Привет, Бартек, я понял о выравнивании DWORD. Насколько я понимаю, речь идет о том, чтобы убедиться, что общий размер даже кратен sizeof(DWORD . Но мой фактический вопрос заключается в том, что DWORD касается распределения общей памяти, которая выравнивается по двойному слову, выполняя bitmapData = (LPBYTE) GlobalAlloc(GMEM_FIXED, bmiHeader- ›biSizeImage) или речь идет о том, чтобы сделать ширину * высоту* bpp с выравниванием по DWORD?   -  person GAP    schedule 04.02.2013
comment
бпп = 4; Чтобы дать четкое представление: данные пикселей имеют строки = 479, столбцы = 638 и bpp = 4; и когда я создаю данные битовой карты, чтобы выровнять их по DWORD, я использую некоторую логику и делаю ширину = 640. Тогда он будет писать из 479 * 638 * BPP => 479 * 640 * BPP. Так что из-за дополненного бита в конце появляется черная линия. Я делаю неправильно здесь?   -  person GAP    schedule 04.02.2013
comment
Выравнивание DWORD означает: каждая строка начинается с границы DWORD. Windows SetBitmapBits API заботится о выравнивании DWORD, при необходимости дополняя каждую строку растрового изображения.   -  person Alex F    schedule 04.02.2013
comment
Это 4 байта на пиксель или 4 бита на пиксель?   -  person Nanhydrin    schedule 04.02.2013


Ответы (2)


Выравнивание DWORD для изображений обычно выполняется по шагу, то есть по ширине, и выражается в байтах, а не в пикселях. Прямо сейчас вы меняете количество пикселей, которое должно быть кратным 4, но это увеличит общее количество байтов в строке намного больше, чем необходимо, фактически, вероятно, на 8 байтов.

Что вы делаете, так это вычисляете (столбцы * биты на пиксель), а затем выравниваете это до 32 бит, чтобы получить свой шаг или ширину. Затем вы можете умножить это на высоту, чтобы получить полный размер изображения.

Таким образом, для вашего изображения размером 479 * 638 638 — это столбцы и, следовательно, ширина.
Если ваше изображение имеет размер 4 байта на пиксель, вам не нужно делать ничего особенного, потому что DWORD — это 4 байта, поэтому ваш общий размер ширина в байтах кратна 4 байтам или 32 битам, 638 * 4 = 2552. Поэтому просто умножьте ее на высоту, чтобы получить общий размер изображения в байтах.

Однако, если ваше изображение было 3 байта на пиксель, тогда 638 * 3 = 1914, а 1914 не является четным числом, кратным 4. Таким образом, вам нужно дополнить 1914 байт до следующего кратного 4.

Обычно я делаю это на С#, поэтому использую следующую формулу:

((ширина и биты на пиксель) + 31) и ~ 31

Затем разделите результат на 8, чтобы получить его в байтах, а не в битах, если это необходимо.

Итак, в вашем случае, если вы сделаете (638 * 24)/8, чтобы получить 1914 байтов, что не является значением, выровненным по DWORD, но с помощью приведенной выше формулы вы получите 1916, что является четным числом 4 байтов и является правильным значением для вашего шага .

person Nanhydrin    schedule 04.02.2013

Я бы сказал, что 4bpp означает 4 бита на пиксель, а не байты :) следовательно, математика выше будет отличаться

person user15039728    schedule 19.01.2021