Как изобразить глубину цвета от 18 бит до глубины цвета 16 бит? - PullRequest
1 голос
/ 29 июня 2009

Я портирую программное обеспечение с глубиной цвета 16 бит на глубину цвета 18 бит. Как я могу преобразовать 16-битные цвета в 18-битные? Спасибо.

Ответы [ 5 ]

1 голос
/ 01 июля 2009

Я не вижу этого в других ответах, но вы хотите, чтобы преобразование из 5 в 6 бит было таким, чтобы двоичный 11111 отображался в 111111, так как оба представляют полный на . Один из способов сделать это - скопировать старший (ые) бит (ы).

red6 = (red5 << 1) | (red5 >> 4);

Если вы используете арифметическое преобразование, имейте в виду, что максимальные значения составляют 31 и 63, а не 32 и 64.

red6 = (red5 * 63 + 15) / 31; // all ints, +15 is for rounding

Если вы заботитесь о других промежуточных значениях, например, если вы хотите, чтобы 16 отображало 32, либо откорректируйте формулу (например, измените 15 на 14), или просто составьте таблицу.

1 голос
/ 29 июня 2009

Предполагая, что 16-битный цвет имеет формат 5-6-5:

// RRRRR-GGGGGG-BBBBB, 16bit -->

//RRRRR0-GGGGGG-BBBBB0, 18bit with the formula below:
Color18 = ((Color16 & 0xF800) << 2) | ((Color16 & 0x07E0) << 1) | ((Color16 & 0x1F) << 1);
1 голос
/ 29 июня 2009

Не зная устройства, я могу только строить догадки.Устройства, как правило, красного, зеленого и синего цветов, поэтому каждый цвет будет иметь 6 бит вариации.Это означает 64 варианта каждого цвета и в общей сложности 262 144 цвета.

Любое растровое изображение может быть масштабировано до этого дисплея.Если вы возьмете каждый компонент (скажем, красный), нормализуете его, затем умножите на 64, у вас будет уменьшенная версия.

Если вы спрашиваете что-то еще или хотите получить более подробную информацию, пожалуйста, спросите.

Обновление:
Существует два 16-битных растровых формата.Один 5-5-5 (5 бит на пиксель), а другой 5-6-5 (зеленый получает дополнительный бит).Для этого преобразования я буду считать 5-5-5.

Для каждого цвета в каждом пикселе вам нужно что-то вроде этого:

NewColor = (oldColor/32.0)*64

Это превратит старый цвет вчисло от 0,0 до 1,0, а затем масштабируйте его до нового диапазона значений.

0 голосов
/ 29 июня 2009

Прежде всего, вам нужно получить доступ к каждому из компонентов цвета (то есть извлечь значение R, значение G и значение B). Способ сделать это будет полностью зависеть от того, как цвет хранится в памяти. Если он хранится как RGB с 5-6-5 битами для компонентов, вы можете использовать что-то вроде этого:

blueComponent  = (colour & 0x1F);
greenComponent = (colour >> 5 ) & 0x3F;
redComponent   = (colour >> 11) & 0x1F;

Это извлечет компоненты цвета для вас, затем вы можете использовать метод, описанный выше, для преобразования каждого из компонентов (я предполагаю, что 18-битный будет использовать 6 бит на компонент):

blueComponent  = (blueComponent  / 32.0) * 64;
//greenComponent = (greenComponent / 64.0) * 64;    // not needed
redComponent   = (redComponent   / 32.0) * 64;

Обратите внимание, что в приведенном выше коде важно использовать 32.0 или какой-либо другой метод, который гарантирует, что ваша программа представит число в виде числа с плавающей запятой. Затем, чтобы объединить компоненты в свой 18-битный цвет, используйте:

colour = (redComponent << 12) | (greenComponent << 6) | blueComponent;
0 голосов
/ 29 июня 2009

Для ответа на вопрос о конверсии

Я не знаком с библиотеками изображений c ++, но уверен, что этот код уже где-то существует. Но если вы хотите, вы можете сделать это самостоятельно.

Каждый пиксель имеет три канала: красный, зеленый и синий. В 16-битной битовой карте каждый канал не имеет одинакового количества бит на канал. Как правило, зеленый является первым, чтобы получить дополнительные биты, потому что человеческий глаз наиболее чувствителен к этому цвету.

Вероятно, 565 - 5 для красного, 6 для зеленого и 5 для синего.

Для 18-битной битовой карты (как указано выше) каждый канал имеет 6 бит. Так что зеленый это легко! Просто скопируйте значение из 16-битного формата в 18-битный формат. Два других канала немного сложнее. Вы должны интерполировать от 5 до 6:

18_Value = (16_Value / 32) * 64 //integers only of course.  You need to round properly to get best results.

И вот оно у вас есть. Если вы еще не знакомы со следующим, я бы посоветовал вам изучить их:

  • Операторы сдвига битов
  • Растровое изображение
  • Pointer Math
  • Выравнивание байтов

- Edit-- Убедитесь, что вы знаете, как все выложено в памяти; RGB или BGR. Это будет мешать вам, если вы сделаете что-нибудь более сложное, чем это, и вы думаете об этом задом наперед (поскольку Грин находится в середине, это не , что важно для этого преобразования).

...