How to convert a PIL ‘Image’ to a Django ‘File’ ¶
from StringIO import StringIO from PIL import Image from PIL import ImageDraw from django.core.files.uploadedfile import InMemoryUploadedFile # load image from db picture = MyModel.objects.get(id=id) # open image with PIL image = Image.open(picture.image) # ... process image with PIL and ImageDraw # make use of StringIO and Django InMemoryUploadedFile to keep image in memory, # without having to write back to the filesystem, # and then bring the file back into memory via an open call buffer = StringIO() image.save(buffer, "PNG") image_file = InMemoryUploadedFile(buffer, None, 'test.png', 'image/png', buffer.len, None) # save back to db new_picture.image.save('test.png', image_file)
Sample usage:
def rotate_picture(instance): """ 'instance' is the model object; 'picture' is the name of the ImageField """ from django.core.files.base import ContentFile from PIL import Image from StringIO import StringIO from django.core.files.uploadedfile import InMemoryUploadedFile file_content = ContentFile(instance.picture.read()) instance.picture.close() img = Image.open(file_content) tempfile = img.rotate(10) buffer = StringIO() tempfile.save(buffer, format='PNG') # note: here we assume .png extension # todo: check and eventually fix extension in filename new_picture_filename = os.path.split(instance.picture.name)[-1] new_picture_file = InMemoryUploadedFile(buffer, None, new_picture_filename, 'image/png', buffer.len, None) instance.picture.save(new_picture_filename, new_picture_file)
References: