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.
Deploy your Django Project - The Correct Way
Learn how to ship your Django Project live to the real world in simple steps.
Deploy your Project NowStep 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
1
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:
- File buffer: This is the JPEG format IO buffer I created in line 5.
- field_name: There wasn't much information about this, if you have any idea then please comment below.
- name: This is the name of the file, make sure you add .jpg at the end.
- content_type: This is pretty self explanatory.
- size: The size in bytes of the file.
- 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"
Footnotes
- InMemoryUploadedFile : https://kite.com/python/docs/django.core.files.uploadedfile.InMemoryUploadedFile↩