RGB color conversion

Página 1/3
| 2 | 3

Por Bit Addict

Resident (34)

Imagen del Bit Addict

27-09-2015, 21:01

Does anyone know how to convert a 24 bits rgb color value (e.g. RGB: 255, 153, 0) to a msx2 equivalent?

When I am right it is a 24 bits rgb to 9 bits rgb color conversion. I am looking for a formula.

Login sesión o register para postear comentarios

Por NYYRIKKI

Enlighted (5918)

Imagen del NYYRIKKI

27-09-2015, 22:24

MSX color component = 24bit color component / 32

Por meits

Scribe (6502)

Imagen del meits

27-09-2015, 22:25

wouldn't that be a division by 36.43?
That wat 255 would become 7.

Por RetroTechie

Paragon (1563)

Imagen del RetroTechie

27-09-2015, 22:26

No formula - you just drop (discard) the least significant bits that don't fit in the less-accurate end result.

Say for example you have a 24 bit value containing 8 bits that represent red, and you want to convert to an RGB value that has only 3 bits representing red. Then you take the 3 most significant bits (out of 8), and put 'em in that 3-bit space. The remaining 5 (less significant) bits you throw away.

Yes that means losing image quality, but that's the whole point of such a conversion: represent the same pixels using fewer bits. One could try various dithering and/or rounding methods to improve results (or perhaps an integer divide with a divisor other than a power of 2), but ultimately you will be discarding part of the image information.

Red / Green / Blue channels can be treated as independent, applying the same method to each. Or not. Again: whatever works, but one way or the other you'll be discarding those least significant bits.

Por NYYRIKKI

Enlighted (5918)

Imagen del NYYRIKKI

27-09-2015, 22:35

Meits wrote:

wouldn't that be a division by 36.43?
That wat 255 would become 7.

No, that would practically leave all the bright colors away as 254 would be already 6 if we are talking about integers. If we start rounding floating points then the brightness problem is not that bad... but anyway... just divide with 32... (This is same as dropping out bits that MSX does not have.)

Por Grauw

Ascended (10581)

Imagen del Grauw

27-09-2015, 22:43

From 8-bit colour component values to 3-bit values: divide by 255, multiply by 7, and round the result. Other way around: divide by 7, multiply by 255, round the result.

The 7 colour component values: 0, 36, 73, 109, 146, 182, 219, 255

When drawing graphics for screen 5, I try to pick only colours with these component values.

Por RetroTechie

Paragon (1563)

Imagen del RetroTechie

27-09-2015, 22:42

@Meits: and what about value 254? Or 253? You round those down to 6? (from a 3-bit value 0,1,...,7)
If yes, that means values 0-6 each represent ~36 possible values in the original, while 7 represents only 1 value in the original. Probably NOT what you want... Tongue
If no (7 represents more values in the original), then you're back to just dropping bits (divide by a power of 2 like NYYRIKKI said) or rounding up/down. Dithering is a better method to preserve a little extra info from the original values.

Por Grauw

Ascended (10581)

Imagen del Grauw

27-09-2015, 22:50

Grauw wrote:

From 8-bit colour component values to 3-bit values: divide by 255, multiply by 7, and round the result. Other way around: divide by 7, multiply by 255, round the result.

Why is this better than dropping the lowest 5 bits (/32)? Because in a 3-bit palette value 0 is fully off, 7 is fully on, and on a 8-bit palette value 0 is fully off and 255 is fully on. You can convert these to a scale from 0 to 1, by either dividing by 7 or dividing by 255.

Assuming all values are linearly distanced (disregarding things like gamma), you want to pick the 3-bit colour that is closest to the original 8-bit colour. For e.g. 8-bit value 224 (0.88), this should be 3-bit value 6 (0.85), not 7 (1.00). This is why you should divide, multiply and round, rather than just dropping bits with an integer division, as it minimises the error.

For this reason when you convert a 3-bit colour component to 24-bit, you also don’t want to pad the binary values with five 0’s, but rather nc = c << 5 + c << 2 + c >> 1 (integer logic) or nc = round(c / 7 * 255) (floating point logic).

Por mars2000you

Enlighted (6228)

Imagen del mars2000you

27-09-2015, 22:50

There's probably a better solution : screen 8 with his 256 colors ! Smile

Why degrad the colors to fit in screen 5 or 7 ?

From the RuMSX help files :

Quote:

SCREEN 8

The color-value in screen 8 can be 0-255, the color is defined by the following formula:

color-number = 4 x R + 32 x G + B. The values for Red and Green can be 0-7, the values for Blue can be 0-3 (they correspond to 0, 2, 4 and 7).

This means that the bits are representing colors as following: G G G R R R B B.

Por NYYRIKKI

Enlighted (5918)

Imagen del NYYRIKKI

27-09-2015, 22:50

@Grauw If you want to take that approach then (VALUE+16)/32 is better... The problem is that you think that 255 should become 7 while actually you should think that 256 should become 8.

Por RetroTechie

Paragon (1563)

Imagen del RetroTechie

27-09-2015, 22:51

For screen modes that use a palette, you can choose colors such that the overall results gets closest to the original.

For example if original has many colors that are very similar, and just a few colors that look very different, you could use a few palette colors for those different ones, and fill the rest of the palette with very similar-looking color values. Then for each RGB value pick the best matching palette entry.

Obviously choosing an optimal palette is a much more complicated job oO than applying the same simple math to each RGB value.

Página 1/3
| 2 | 3