(moved to Show & Tell)
One of the really cool features of Anvil is that it has a built-in file loader and a way to save binary media objects in datatables. One the occasion that you might need to serialize a binary image for transmission via a server function or REST API, the process is a bit less straightforward. Having worked through this a bit, I wanted to post a quick summary for future reference. This example uploads an image, serializes it for transmission to a server module, decodes it, resizes it to a thumbnail, and sends it back.
Here is the demo:
https://serialize_decode_resize_image.anvil.app
And a clone: clone:
The key client-side code:
def client_image_to_uri(file_bytes): # Provide an argument like self.file_loader_1.file.get_bytes() # This will return a JSON serializable string you can use with APIs img_uri = "data:image/png;base64," + base64.b64encode(file_bytes) return img_uri
They key server-side code
@anvil.server.callable def create_thumbnail(full_image_base64_string): # decode the base64 string to an image full_image = Image.open(BytesIO(base64.b64decode(full_image_base64_string))) # resize it to a thumbnail thumbnail_image = full_image.resize((70,70)) # create a byte array from the thumbnail thumbnail_byte_array = BytesIO() thumbnail_image.save(thumbnail_byte_array, format='PNG') thumbnail_byte_array = thumbnail_byte_array.getvalue() # encode the byte array to a base64 string thumbnail_base64_string = base64.b64encode(thumbnail_byte_array).decode('utf8') return thumbnail_base64_string