2424bytes 0-1 -> R | G value of pixel (superpixel layer #)
2525bytes 2-3 -> # consecutive occurences
2626"""
27+ from io import BytesIO
2728import itertools
2829import struct
2930
3031import numpy as np
3132from PIL import Image
3233
34+ _BACKGROUND_RGBA = [255 , 255 , 255 , 255 ]
35+ _HEADER_LENGTH = 6 * 4
36+
3337
3438def encode (image ):
35- """Converts a `PIL.Image` to a `io.BytesIO` with LBX encoded data.
39+ """Converts a RGB `PIL.Image` to a `io.BytesIO` with LBX encoded data.
3640
3741 Args:
3842 image (`PIL.Image`): The image to encode.
3943
4044 Returns:
4145 A `io.BytesIO` containing the LBX encoded image.
4246 """
43- return image
47+ im = image .convert ('RGBA' )
48+ pixel_words = np .array (im ).reshape (- 1 , 4 )
49+
50+ colormap = list (filter (lambda x : not np .all (x == _BACKGROUND_RGBA ),
51+ np .unique (pixel_words , axis = 0 )))
52+
53+
54+ input_byte_len = len (np .array (im ).flat )
55+ buff = BytesIO (bytes ([0 ] * (len (colormap ) * 4 + input_byte_len )))
56+
57+ offset = _HEADER_LENGTH # make room for header
58+ for color in colormap :
59+ struct .pack_into ('<BBBB' , buff .getbuffer (), offset , * color )
60+ offset += 4
61+
62+ # write header
63+ struct .pack_into ('<iiiiii' , buff .getbuffer (), 0 ,
64+ 1 , im .width , im .height , input_byte_len , len (colormap ),
65+ offset - len (colormap ) - _HEADER_LENGTH )
66+
67+ return buff
4468
4569
4670def decode (lbx ):
@@ -53,13 +77,13 @@ def decode(lbx):
5377 A `PIL.Image` of the decoded data.
5478 """
5579 version , width , height , byteLength , numColors , numBlocks = \
56- map (lambda x : x [0 ], struct .iter_unpack ('<i' , lbx .read (24 )))
80+ map (lambda x : x [0 ], struct .iter_unpack ('<i' , lbx .read (_HEADER_LENGTH )))
5781 colormap = np .array (
5882 list (_grouper (
5983 map (lambda x : x [0 ],
6084 struct .iter_unpack ('<B' , lbx .read (4 * numColors ))),
6185 4 )) +
62- [[ 0 , 0 , 0 , 255 ] ]
86+ [_BACKGROUND_RGBA ]
6387 )
6488
6589 image_data = np .zeros ((width * height , 4 ), dtype = 'uint8' )
0 commit comments