How does one convert 16-bit RGB565 to 24-bit RGB888?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
RGB565 stores red, green, and blue in 16 bits total, while RGB888 stores each channel in a full 8 bits. Converting from RGB565 to RGB888 means extracting the 5-bit or 6-bit channels, then expanding them to 8-bit values so they can be used in a 24-bit pixel format.
Understand the Bit Layout
RGB565 packs the channels like this:
- red: 5 bits
- green: 6 bits
- blue: 5 bits
The bit layout inside one 16-bit pixel is:
rrrrrggggggbbbbb
RGB888, by contrast, stores one byte for each channel:
rrrrrrrr gggggggg bbbbbbbb
So the job is not just copying bits. You must separate the source channels and scale them into the wider target range.
Extract the RGB565 Channels
Start by masking and shifting:
After extraction, the values are still in the smaller 0..31 or 0..63 ranges. They are not yet valid 8-bit channels.
Expand to 8 Bits
The common fast approximation is to shift left and copy the top bits into the low end:
Why this works:
- a 5-bit value becomes approximately
value * 255 / 31 - a 6-bit value becomes approximately
value * 255 / 63
The bit-replication trick is fast and visually close to exact scaling, which is why it is common in graphics code and embedded systems.
Full Conversion Function
If you need one packed 24-bit integer instead of three separate bytes, combine the expanded channels:
Exact Scaling Versus Fast Approximation
If accuracy matters more than speed, you can scale mathematically:
The exact formula is a little slower, but it makes the mapping explicit. In many systems, the replicated-bit method is preferred because it is cheap and the visual difference is usually negligible.
Byte Order Is a Separate Issue
A common source of bugs is confusing color format with byte order. RGB565 describes how bits are assigned to channels. Endianness describes how the two bytes of the 16-bit value are stored in memory or received on a wire.
If the source bytes arrive in the wrong order, fix that first:
Only after reconstructing the correct 16-bit value should you extract the channel fields.
Common Pitfalls
- Treating RGB565 as if each color already had 8 bits leads to washed-out or distorted colors.
- Forgetting that green uses 6 bits, not 5, produces visibly wrong green values.
- Confusing endianness with channel layout can make a correct conversion formula still produce the wrong color.
- Using only left shifts without filling lower bits creates a darker, less accurate 8-bit result.
- Packing into a 24-bit integer without casting to
uint32_tfirst can cause accidental overflow in C.
Summary
- RGB565 stores
5/6/5bits for red, green, and blue. - Convert by masking and shifting out each channel, then expanding to 8 bits.
- The common fast expansion uses bit replication such as
(value << 3) | (value >> 2). - Check byte order separately, because endianness problems can look like color-conversion bugs.

