Как эффективно визуализировать изображение с 24 битами на дюйм на 32-битном дисплее?

Прежде всего, я программирую в контексте ядра, поэтому существующие библиотеки не существуют. На самом деле этот код собирается войти в мою собственную библиотеку.

Два вопроса, один из которых важнее другого:

  1. Как следует из заголовка, как я могу эффективно визуализировать изображение с 24 битами на пиксель на устройство с 32 битами на дюйм, предполагая, что у меня есть адрес буфера кадра?

В настоящее время у меня есть этот код:

void BitmapImage::Render24(uint16_t x, uint16_t y, void (*r)(uint16_t, uint16_t, uint32_t))
{
uint32_t imght = Math::AbsoluteValue(this->DIB->GetBitmapHeight());
uint64_t ptr = (uint64_t)this->ActualBMP + this->Header->BitmapArrayOffset;

uint64_t rowsize = ((this->DIB->GetBitsPerPixel() * this->DIB->GetBitmapWidth() + 31) / 32) * 4;

uint64_t oposx = x;
uint64_t posx = oposx;
uint64_t posy = y + (this->DIB->Type == InfoHeaderV1 && this->DIB->GetBitmapHeight() < 0 ? 0 : this->DIB->GetBitmapHeight());for(uint32_t d = 0; d < imght; d++)
{
for(uint32_t w = 0; w < rowsize / (this->DIB->GetBitsPerPixel() / 8); w++)
{
r(posx, posy, (*((uint32_t*)ptr) & 0xFFFFFF));
ptr += this->DIB->GetBitsPerPixel() / 8;
posx++;
}
posx = oposx;
posy--;
}
}

r — это указатель на функцию в стиле PutPixel, которая принимает параметры x, y и color.
Очевидно, этот код ужасно медленный, так как построение пикселов по одному никогда не является хорошей идеей.

Для моего кода рендеринга с 32 битами на секунду (о котором у меня также есть вопрос, об этом позже) я могу легко Memory :: Copy () растровый массив (я загружаю здесь bmp файлы) в буфер кадра.
Тем не менее, как я могу сделать это с изображениями 24bpp? На дисплее 24bpp это было бы хорошо, но я работаю с 32bpp.

Одно из решений, о котором я могу подумать сейчас, — это создать еще один массив растровых изображений, который по существу содержит значения 0x00 (цвет) и использование для рисования на экране — хотя я не думаю, что это очень хорошо, поэтому я ищу для лучшей альтернативы.

Следующий вопрос:
2. Принимая во внимание, по понятным причинам, невозможно просто Memory :: Copy () весь массив сразу в буфер кадра, следующая лучшая вещь будет копировать их строка за строкой.

Есть ли способ лучше?

0

Решение

В основном как то так:

for (uint32_t l = 0; l < h; ++l) // l line index in pixels
{
// srcPitch is distance between lines in bytes
char*     srcLine = (char*)srcBuffer + l * srcPitch;
unsigned* trgLine = ((unsigned*)trgBuffer) + l * trgPitch;

for (uint32_t c = 0; c < w; ++c) // c is column index in pixels
{
// build target pixel. arrange indexes to fit your render target (0, 1, 2)
++(*trgLine) = (srcLine[0] << 16) | (srcLine[1] << 8)
| srcLine[2] | (0xff << 24);
srcLine += 3;
}
}

Несколько заметок:
— лучше записывать в другой буфер, чем в буфер рендеринга, чтобы изображение отображалось сразу.
— Использование функций для размещения пикселей, как вы сделали, очень (очень, очень) медленно.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]