Skip to content

Commit bd6d52d

Browse files
authored
Merge pull request #48 from philsuth/rgb565
Add RGB565 format support
2 parents 1cd7476 + 3db43b3 commit bd6d52d

File tree

1 file changed

+54
-1
lines changed

1 file changed

+54
-1
lines changed

adafruit_framebuf.py

+54-1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,57 @@ def fill_rect(framebuf, x, y, width, height, color):
126126
height -= 1
127127

128128

129+
class RGB565Format:
130+
"""
131+
This class implements the RGB565 format
132+
It assumes a little-endian byte order in the frame buffer
133+
"""
134+
135+
@staticmethod
136+
def color_to_rgb565(color):
137+
"""Convert a color in either tuple or 24 bit integer form to RGB565,
138+
and return as two bytes"""
139+
if isinstance(color, tuple):
140+
hibyte = (color[0] & 0xF8) | (color[1] >> 5)
141+
lobyte = ((color[1] << 5) & 0xE0) | (color[2] >> 3)
142+
else:
143+
hibyte = ((color >> 16) & 0xF8) | ((color >> 13) & 0x07)
144+
lobyte = ((color >> 5) & 0xE0) | ((color >> 3) & 0x1F)
145+
return bytes([lobyte, hibyte])
146+
147+
def set_pixel(self, framebuf, x, y, color):
148+
"""Set a given pixel to a color."""
149+
index = (y * framebuf.stride + x) * 2
150+
framebuf.buf[index : index + 2] = self.color_to_rgb565(color)
151+
152+
@staticmethod
153+
def get_pixel(framebuf, x, y):
154+
"""Get the color of a given pixel"""
155+
index = (y * framebuf.stride + x) * 2
156+
lobyte, hibyte = framebuf.buf[index : index + 2]
157+
r = hibyte & 0xF8
158+
g = ((hibyte & 0x07) << 5) | ((lobyte & 0xE0) >> 5)
159+
b = (lobyte & 0x1F) << 3
160+
return (r << 16) | (g << 8) | b
161+
162+
def fill(self, framebuf, color):
163+
"""completely fill/clear the buffer with a color"""
164+
rgb565_color = self.color_to_rgb565(color)
165+
for i in range(0, len(framebuf.buf), 2):
166+
framebuf.buf[i : i + 2] = rgb565_color
167+
168+
def fill_rect(self, framebuf, x, y, width, height, color):
169+
"""Draw a rectangle at the given location, size and color. The ``fill_rect`` method draws
170+
both the outline and interior."""
171+
# pylint: disable=too-many-arguments
172+
rgb565_color = self.color_to_rgb565(color)
173+
for _y in range(2 * y, 2 * (y + height), 2):
174+
offset2 = _y * framebuf.stride
175+
for _x in range(2 * x, 2 * (x + width), 2):
176+
index = offset2 + _x
177+
framebuf.buf[index : index + 2] = rgb565_color
178+
179+
129180
class RGB888Format:
130181
"""RGB888Format"""
131182

@@ -203,6 +254,8 @@ def __init__(self, buf, width, height, buf_format=MVLSB, stride=None):
203254
self.format = MHMSBFormat()
204255
elif buf_format == RGB888:
205256
self.format = RGB888Format()
257+
elif buf_format == RGB565:
258+
self.format = RGB565Format()
206259
else:
207260
raise ValueError("invalid format")
208261
self._rotation = 0
@@ -419,7 +472,7 @@ def image(self, img):
419472
if self.rotation in (1, 3):
420473
width, height = height, width
421474

422-
if isinstance(self.format, RGB888Format) and img.mode != "RGB":
475+
if isinstance(self.format, (RGB565Format, RGB888Format)) and img.mode != "RGB":
423476
raise ValueError("Image must be in mode RGB.")
424477
if isinstance(self.format, (MHMSBFormat, MVLSBFormat)) and img.mode != "1":
425478
raise ValueError("Image must be in mode 1.")

0 commit comments

Comments
 (0)