Преобразование изображения из формата 24 bpp в 16 bpp - PullRequest
1 голос
/ 02 ноября 2011

У меня есть изображение, т.е. нарисованное с использованием вызовов Windows GDI (24 bpp), и мне нужно преобразовать это изображение в 16 bpp.Это на Windows Mobile.

 24 bpp - RGB (rrrrrrrr gggggggg bbbbbbbb)
 16 bpp - RGB (rrrrr gggggg bbbbb)

Для этого я использую следующий код

for (int x = 0; x < iScreenSize; x++)
{
    *iPixel1= (*iPixel & 0x0000001F) |
              (*iPixel & 0x00003F00) >> 3 | 
              (*iPixel & 0x001F0000) >> 5;
}

Код работает нормально, но производительность не так хороша, так как я изменяю пиксель за пикселем,Можете ли вы предложить какие-либо возможные улучшения для этого преобразования?

Заранее спасибо

1 Ответ

6 голосов
/ 02 ноября 2011

Ваш код не завершен; вы не показываете типы указателей или то, как вы их увеличиваете. Количество операций, которые вы выполняете на пиксель, выглядит довольно оптимальным, поэтому я предполагаю, что любая медлительность происходит из-за невыровненного доступа к памяти. Это можно исправить, развернув цикл и выполнив 4 пикселя за раз. Также компилятор должен быть достаточно умен, чтобы оптимизировать множественный доступ к одному и тому же указателю, но давайте предположим, что это не так, и вместо этого скопируем их во временные переменные. Я также собираюсь предположить, что вы хотите сохранить верхние биты каждого цветового канала, а не младшие биты в вашем примере кода.

UINT32 * iPixel;
UINT16 * iPixel1;
for (int x = 0; x < iScreenSize; x+=4)
{
    UINT32 dw1 = *iPixel++;
    UINT32 dw2 = *iPixel++;
    UINT32 dw3 = *iPixel++;
    *iPixel1++ = (dw1 & 0x000000F8) >> 3 |
                 (dw1 & 0x0000FC00) >> 5 |
                 (dw1 & 0x00F80000) >> 8;
    *iPixel1++ = (dw1 & 0xF8000000) >> 27 |
                 (dw2 & 0x000000FC) << 3 |
                 (dw2 & 0x0000F800);
    *iPixel1++ = (dw2 & 0x00F80000) >> 19 |
                 (dw2 & 0xFC000000) >> 21 |
                 (dw3 & 0x000000F8) << 8;
    *iPixel1++ = (dw3 & 0x0000F800) >> 11 |
                 (dw3 & 0x00FC0000) >> 13 |
                 (dw3 & 0xF8000000) >> 16;
}
...