pythondjangopython-imaging-librarydjango-file-uploaddjango-uploads

How do you convert a PIL `Image` to a Django `File`?


I'm trying to convert an UploadedFile to a PIL Image object to thumbnail it, and then convert the PIL Image object that my thumbnail function returns back into a File object. How can I do this?


Solution

  • The way to do this without having to write back to the filesystem, and then bring the file back into memory via an open call, is to make use of StringIO and Django InMemoryUploadedFile. Here is a quick sample on how you might do this. This assumes that you already have a thumbnailed image named 'thumb':

    import StringIO
    
    from django.core.files.uploadedfile import InMemoryUploadedFile
    
    # Create a file-like object to write thumb data (thumb data previously created
    # using PIL, and stored in variable 'thumb')
    thumb_io = StringIO.StringIO()
    thumb.save(thumb_io, format='JPEG')
    
    # Create a new Django file-like object to be used in models as ImageField using
    # InMemoryUploadedFile.  If you look at the source in Django, a
    # SimpleUploadedFile is essentially instantiated similarly to what is shown here
    thumb_file = InMemoryUploadedFile(thumb_io, None, 'foo.jpg', 'image/jpeg',
                                      thumb_io.len, None)
    
    # Once you have a Django file-like object, you may assign it to your ImageField
    # and save.
    ...
    

    Let me know if you need more clarification. I have this working in my project right now, uploading to S3 using django-storages. This took me the better part of a day to properly find the solution here.