Creating Image Thumbnails and Crops In Python Using S3 and PIL
If you ever plan on designing a web application that requires image uploading, you will probably need to create image thumbnails. Amazon S3 is a great place to store images because it is very cheap, reliable, and has a robust API (in python accessible via boto). Although creating thumbnails is pretty easy, I believe having both scenarios described below in a single place is useful, as I have had to look at multiple stackoverflow posts to find these solutions.
The two different scenarios we are going to go over here are the following
The images are already on the internet, so you need to download them, resize them, and upload them to Amazon S3
The images are on a local hard drive, so we need to handle image upload to the webserver, processing, and then uploading to Amazon S3.
The Images Already Reside On The Internet
If you’re images already reside on the internet, you do not need to handle the image upload mechanism. Your software needs to be able to download the image, perform and processing on the image, and then upload the results to Amazon S3.
Downloading an image from the internet is pretty easy using Python’s excellent requests library:
It is important you store the image in a StringIO object, because then you can read it into PIL without saving it to disk. Once you have the image data you can create a thumbnail using the following method:
The method above forced the width of the image to be basewidth, which for my application is 400 pixels. If you have x,y,w,h, and you want to crop the image instead, you can use a method like the following
You need a special function for uploading an image to S3 using boto via a StringIO. That method looks like the following:
The Images Resize On The Customer’s Local Hard drive
If the image does not resize on the internet, you’re going to have to handle the upload in your web application also. There are a variety of different jquery uploaders that can be used to upload files to a web server. My favorite at the moment is dropzone.js, but really anything will work. Using django, you can handle an AJAX request for a file upload as follows:
And the save_upload method used above performs the following: