OpenGL C ++: Как преобразовать 32-битный файл PNG в 16-битный файл 565RGB - PullRequest
0 голосов
/ 22 февраля 2012

Я пытаюсь конвертировать 32-битные файлы PNG в 16-битные форматы файлов, я понимаю, как конвертировать 16-битные форматы файлов между собой (например, RGB565 RGBA4444), однако я не уверен, как перейти к конвертации из 32-битных в16 бит.

Мои основные вопросы: как мне найти, как хранятся 32-битные png-файлы (каждый из которых по 8 бит назначен значениям R, B, G и A)?

КакЯ потерял точность, но все еще сохранил примерно то же значение?

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

Ответы [ 2 ]

1 голос
/ 22 февраля 2012

Было бы намного лучше использовать libpng , чем реализовывать это вручную.

0 голосов
/ 22 февраля 2012

Я не знаком с точной компоновкой 32-битного пикселя PNG, но, предполагая, что он относительно совместим с другими форматами, вы, вероятно, захотите сделать что-то похожее на это:

// Get the pixel from the png:
unsigned int pngPixel = getPngPixel();

unsigned char r = (pngPixel & 0xFF000000) >> 24;
unsigned char g = (pngPixel & 0x00FF0000) >> 16;
unsigned char b = (pngPixel & 0x0000FF00) >> 8;
unsigned char a = (pngPixel & 0x000000FF);

// you can collapse this to one line, but for clarity...
// masking off the least significant bits.
unsigned short rgb565Pixel = (r & 0xF8) << 11; 
rgb565Pixel |= (g & 0xFC) << 5;
rgb565Pixel |= (b & 0xF8);

// Again you could collapse this down to one line, but for clarity...
// masking off the least significant bits.
unsigned short rgba4Pixel = (r & 0xF0) << 12;
rgba4Pixel |= (g & 0xF0) << 8;
rgba4Pixel |= (b & 0xF0) << 4;
rgba4Pixel |= (a & 0xF0);  

Рассмотрим этот псевдокод.

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

unsigned int convertColor(unsigned char c, unsigned int oldMax, unsigned int newMax) {
   double oldColor = c;
   double percentOfMax = oldColor / oldMax;
   return ((unsigned int)(newMax * percentOfMax)) & newMax;
}

// now we can do this
unsigned short rgba4Pixel = convertColor(r, 0xFF, 0x0F) << 12;
rgba4Pixel |= convertColor(g, 0xFF, 0x0F) << 8;
rgba4Pixel |= convertColor(b, 0xFF, 0x0F) << 4;
rgba4Pixel |= convertColor(a, 0xFF, 0x0F); 
...