Is there a way to create a GIF in memory and send it as a flask response?

Viewed 346

Right now I'm creating the GIF saving locally and only then sending it as a response in flask. That seems really wasteful. Is there a way to avoid saving it completely?

Because I've done exactly that for a JPG image, but it wouldn't really work with my GIF creation method.

My JPG response method:

from flask import make_response
import cv2
        
   def compressedJPG(img):
        COMPRESSION = 100  # 100 = no compression, the lower the number the higher the compression
        encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), COMPRESSION]
        _, converted = cv2.imencode('.jpg', img, encode_param)
        return converted.tobytes()
        
   def BGR2Response(img):
            jpg = compressedJPG(img)
            response = make_response(jpg)
            response.headers['Content-Type'] = 'image/jpg'
            return response

Here is the function I use to create the GIF

import os
from PIL import Image

VIDEO_FPS = 30
PHOTO_STEP = 4


def directory2GIF(dir):
    _, _, filenames = next(os.walk(dir))
    filenames.sort()
    images = [Image.open(os.path.join(dir, filename)) for i, filename in enumerate(
        filenames) if (i % PHOTO_STEP == 0 and '.jpg' in filename)]
    print("Number of images used:", len(images))
    images[0].save('test.gif',
                   save_all=True, append_images=images[1:], duration=(1000//VIDEO_FPS)*PHOTO_STEP)
1 Answers

Although you don't say that, I think you want to create an animated GIF in memory and return it to the browser. So I think you want:

import io

buffer = io.BytesIO()

# Save to memory buffer 
images[0].save(buffer, format="GIF", ...)

GIFforClient = buffer.getvalue()
Related