Off course there is a way to make the b64 from DALLE smaller by compressing it. You can try the PIL library with Python. CHeck the following example where we can use the PIL library for resizing and compressing it before converting it to base64.
import io
from PIL import Image
# convert base64 image to bytes
image_bytes = io.BytesIO(base64.b64decode(image))
# open image with PIL
pil_image = Image.open(image_bytes)
# this is to resize and compress image
max_size = 256
quality = 80 # adjust quality to get smaller file size
pil_image = pil_image.resize((max_size, max_size))
pil_image.save(image_bytes, format='JPEG', quality=quality)
# convert compressed image to base64
compressed_image = base64.b64encode(image_bytes.getvalue()).decode('utf-8')
Answer from N Miaoulis on Stack OverflowOff course there is a way to make the b64 from DALLE smaller by compressing it. You can try the PIL library with Python. CHeck the following example where we can use the PIL library for resizing and compressing it before converting it to base64.
import io
from PIL import Image
# convert base64 image to bytes
image_bytes = io.BytesIO(base64.b64decode(image))
# open image with PIL
pil_image = Image.open(image_bytes)
# this is to resize and compress image
max_size = 256
quality = 80 # adjust quality to get smaller file size
pil_image = pil_image.resize((max_size, max_size))
pil_image.save(image_bytes, format='JPEG', quality=quality)
# convert compressed image to base64
compressed_image = base64.b64encode(image_bytes.getvalue()).decode('utf-8')
I'm not sure why N Miaolis's code was not working for my case. I guess saving the new lower quality image in the same BytesIO object did not work for me
I created this method where the image_format is PNG or JPG and the picture.image is a bytes object of the base64 encoded image e.g. b'iVBORw0KGgoAAAA....'
The max_size parameter is used to set the dimensions squared and as for the quality I do not recommend going below 70 as far too few details can be noticed.
def compress_image(picture, quality=70, max_size=256):
image_bytes = io.BytesIO(base64.b64decode(picture.image))
image_format = parse_image_format(picture.image_format)
pil_image = Image.open(image_bytes)
pil_image = pil_image.resize((max_size, max_size))
output_buffer = io.BytesIO()
pil_image.save(output_buffer, format=image_format, quality=quality)
compressed_image = output_buffer.getvalue()
picture.image = base64.b64encode(compressed_image)
python - How do I compress base64 data using stringIO into a buffer? - Stack Overflow
encode - Compressing and Encoding the contents of a file in python - Stack Overflow
How to resize base64 encoded image in python - Stack Overflow
Compress GAE Blob images using Python Base64? - Stack Overflow
Yes, encoding the images directly using base64 seems like a reasonable approach, given they're only thumbnails. This is similar to using data: URLs in a webpage for the same reason.
Doing it should be as simple as calling the same Images API transforms you do in your regular code to generate the thumbnail, then serializing the resulting output as base64. You probably want to cache the result in memcache - in both handlers - to prevent redundant calls to the Images API. Alternately, you could calculate the thumbnail when the image is first uploaded, and store it alongside the full-size image.
Perhaps you just need to call read()
encoded = item.image.read().encode('base64')
If you're dealing with images of any great size, you'll want to encode in chunks (i.e. read(4096) multiple times, encoding each piece).