@@ -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+
129180class 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