Privacy Policy
Snippets index

  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: