Skip to content

Add support for RGB565 images - #12915

Open
task-jp wants to merge 3 commits into
slint-ui:masterfrom
task-jp:rgb565-images
Open

Add support for RGB565 images#12915
task-jp wants to merge 3 commits into
slint-ui:masterfrom
task-jp:rgb565-images

Conversation

@task-jp

@task-jp task-jp commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

RGB565 is the native format of most embedded displays and of the software renderer's Rgb565Pixel target. Add
Image::from_rgb565(SharedPixelBuffer) and a SharedImageBuffer::RGB565 variant so such buffers can be displayed without converting them to RGB8 first.

The software renderer draws RGB565 textures directly, with no per-pixel conversion at all when the target pixel is also RGB565 (new TargetPixel::from_rgb565, identity for Rgb565Pixel). Qt uploads as QImage::Format_RGB16 (zero-copy), Skia uses ColorType::RGB565, femtovg and anyrender expand to RGB(A)8 at texture upload.

Rgb565Pixel moves from i-slint-renderer-software to i-slint-core (the old path keeps a re-export), and in C++ from slint-platform.h to the slint namespace (slint::platform::Rgb565Pixel stays as an alias). SharedPixelBuffer::as_bytes' bound is relaxed from rgb::ComponentBytes to rgb::Pod with bytemuck casting, so pixel types outside the rgb crate can use it.

Same file-by-file structure as the pending Gray8 support (#11331).

Fixes #12830

RGB565 is the native format of most embedded displays and of the
software renderer's Rgb565Pixel target. Add
Image::from_rgb565(SharedPixelBuffer<Rgb565Pixel>) and a
SharedImageBuffer::RGB565 variant so such buffers can be displayed
without converting them to RGB8 first.

The software renderer draws RGB565 textures directly, with no
per-pixel conversion at all when the target pixel is also RGB565
(new TargetPixel::from_rgb565, identity for Rgb565Pixel). Qt uploads
as QImage::Format_RGB16 (zero-copy), Skia uses ColorType::RGB565,
femtovg and anyrender expand to RGB(A)8 at texture upload.

Rgb565Pixel moves from i-slint-renderer-software to i-slint-core (the
old path keeps a re-export), and in C++ from slint-platform.h to the
slint namespace (slint::platform::Rgb565Pixel stays as an alias).
SharedPixelBuffer::as_bytes' bound is relaxed from rgb::ComponentBytes
to rgb::Pod with bytemuck casting, so pixel types outside the rgb
crate can use it.

Same file-by-file structure as the pending Gray8 support (slint-ui#11331).

ChangeLog: Added `Image::from_rgb565` to create images from RGB565 pixel buffers
Fixes slint-ui#12830

@R-Cramer4 R-Cramer4 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking into implementing this myself a while ago so I'm happy to see it is getting worked on. I just have one minor nit with it, but otherwise it looks solid.

Comment on lines +879 to +881
((value & 0xf800) >> 8) as u8,
((value & 0x07e0) >> 3) as u8,
((value & 0x001f) << 3) as u8,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably use R_MASK, G_MASK, and B_MASK instead of raw hex values

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I went one step further and used the Rgb565Pixel accessors, which removes the masks from this spot entirely.

…efault

Review feedback: the open-coded masks duplicated what the accessors
already do.
cspell parses 0xffu8 as the unknown word "xffu". Write the literals
like the existing rgb565 test in the software renderer does.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support RGB565 pixel buffers in Image (Image::from_rgb565)

2 participants