How to save Base64 encoded image to Django ImageField?

I had to create an API that had to accept an image in Base64 encoded format and save it to Django image field, which requires an image file. So today I learned how to do this.

Step 1: B64 to PIL

The first step will be to convert this B64 image to an image file in memory, I will be using Pillow for this. You can install Pillow using this bash command.

$ pip install pillow

Make sure you have pip installed. If you're using Linux or Mac OS, then you might have to use pip3 instead of pip. But I'm using virtual env, so who cares.

after that, write this function.

import base64
import io
from PIL import Image

def decodeDesignImage(data):
    try:
        data = base64.b64decode(data.encode('UTF-8'))
        buf = io.BytesIO(data)
        img = Image.open(buf)
        return img
    except:
        return None

This function will return a PIL image if the B64 data is valid, or it will return None.

Step 2: PIL to Django ImageField

After getting the PIL image, wrote a function that will take this PIL image, convert it into a JPEG file buffer and then inserted it to Database instance using InMemoryUploadedFile

What is InMemoryUploadedFile? This is basically a representation of the image in memory, that's as simple as it is.

from django.core.files.uploadedfile import InMemoryUploadedFile

img = decodeDesignImage(data)
img_io = io.BytesIO()
img.save(img_io, format='JPEG')
design.image = InMemoryUploadedFile(img_io, field_name=None, name=token+".jpg", content_type='image/jpeg', size=img_io.tell, charset=None)
design.save()

The InMemoryUploadedFile class takes 6 parameters:

  1. File buffer: This is the JPEG format IO buffer I created in line 5.
  2. field_name: There wasn't much information about this, if you have any idea then please comment below.
  3. name: This is the name of the file, make sure you add .jpg at the end.
  4. content_type: This is pretty self explanatory.
  5. size: The size in bytes of the file.
  6. charset: The character set, the file data is using. In this case None.

Now if you check your Media folder, you'll see that image as if you've uploaded it via a form.

So that's it for today's "Today I Learned"

37