@@ -126,6 +126,57 @@ def fill_rect(framebuf, x, y, width, height, color):
126
126
height -= 1
127
127
128
128
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
+
129
180
class RGB888Format :
130
181
"""RGB888Format"""
131
182
@@ -203,6 +254,8 @@ def __init__(self, buf, width, height, buf_format=MVLSB, stride=None):
203
254
self .format = MHMSBFormat ()
204
255
elif buf_format == RGB888 :
205
256
self .format = RGB888Format ()
257
+ elif buf_format == RGB565 :
258
+ self .format = RGB565Format ()
206
259
else :
207
260
raise ValueError ("invalid format" )
208
261
self ._rotation = 0
@@ -419,7 +472,7 @@ def image(self, img):
419
472
if self .rotation in (1 , 3 ):
420
473
width , height = height , width
421
474
422
- if isinstance (self .format , RGB888Format ) and img .mode != "RGB" :
475
+ if isinstance (self .format , ( RGB565Format , RGB888Format ) ) and img .mode != "RGB" :
423
476
raise ValueError ("Image must be in mode RGB." )
424
477
if isinstance (self .format , (MHMSBFormat , MVLSBFormat )) and img .mode != "1" :
425
478
raise ValueError ("Image must be in mode 1." )
0 commit comments