Pillow resize pixelating images - Django/Pillow

django, image, python, python-imaging-library

Solution

With this code I get this image (Python 2.7, Pillow 2.4.0) which has no pixelating.

from PIL import Image

large_size = (1920, 1200)

im = Image.open("babu_980604.jpeg")

image_w, image_h = im.size
aspect_ratio = image_w / float(image_h)
new_height = int(large_size[0] / aspect_ratio)

if new_height < 1200:
    final_width = large_size[0]
    final_height = new_height
else:
    final_width = int(aspect_ratio * large_size[1])
    final_height = large_size[1]

imaged = im.resize((final_width, final_height), Image.ANTIALIAS)

imaged.show()
imaged.save("out.jpg", quality=90)

The main difference between this and your code is it gets `image_w` and `image_h` directly from the opened image instead of `get_image_dimensions(image)`, whose implementation is not shown.

Some minor things in your code:

You could set `infile` before the `with open(...)` and use it there too.

`final_size` isn't used and can be removed, or otherwise use it in `im.resize()`.

`base_width` could be replaced by `large_size[0]`, as you also use `large_size[1]` elsewhere.

`image` is set to `requests.FILES['file']` but you also use `requests.FILES['file']` directly. You could reuse `image`.

`global random` probably isn't needed.

Problem

I am developing an image uploader in Django. After the image has been uploaded and saved on disk, I'm trying to resize the saved image while maintaing its aspect ratio. I am using Pillow for image processing/resizing. The problem arises when I try to resize the image, it's getting pixelated even though the resized image's aspect ratio is same as that of the original image. Original Saved Image : https://www.dropbox.com/s/80yk6tnwt3xnoun/babu_980604.jpeg Resized Pixelated Image: https://www.dropbox.com/s/bznodpk4t4xlyqp/babu_736302.large.jpeg I've tried googling this problem and have checked out other related links on stackoverflow as well, like How do I resize an image using PIL and maintain its aspect ratio? Resize image maintaining aspect ratio AND making portrait and landscape images exact same size? but the problem still persists. Versions: Django=1.6.4 Pillow=2.4.0 Everything has been setup inside virtualenv. Please help! PS : I'm a newbie to the world of Python/Django Here's my code snippet : ``` import json import os import hashlib from datetime import datetime from operator import itemgetter import random from random import randint from django.views.decorators.csrf import csrf_exempt, csrf_protect from django.http import (HttpResponse, HttpResponseRedirect) from django.core.context_processors import csrf from django.core.files.images import get_image_dimensions from django.shortcuts import render, redirect from django.forms.models import model_to_dict from django.views.decorators.csrf import csrf_exempt from PIL import Image, ImageOps from django.views.decorators.csrf import csrf_exempt, csrf_protect import settings from hashlib import md5 from django import forms from beardedavenger.models import * from django.views.decorators.http import require_POST import pdb import requests def imagehandler(requests): if requests.method == 'POST': filename = requests.FILES['file'].name file_extension = filename.split('.')[len(filename.split('.')) - 1].lower() errors = [] username = 'nit' global random #allowed image types are png, jpg, jpeg, gif if file_extension not in settings.IMAGE_FILE_TYPES: errors.append('The image file you provided is not valid. Only the following extensions are allowed: %s' % ', '.join(settings.IMAGE_FILE_TYPES)) else: image = requests.FILES['file'] image_w, image_h = get_image_dimensions(image) rand = str(random.randint(100000,999999)) with open(settings.MEDIA_ROOT + username + '_' + rand + '.jpeg', 'wb+') as destination: for chunk in requests.FILES['file'].chunks(): destination.write(chunk) large_size = (1920, 1200) infile = settings.MEDIA_ROOT + username + '_' + rand + ".jpeg" large_file = settings.MEDIA_ROOT + username + '_' + rand +".large" try: im = Image.open(infile) base_width = large_size[0] aspect_ratio = float(image_w / float(image_h)) new_height = int(base_width / aspect_ratio) if new_height < 1200: final_width = base_width final_height = new_height else: final_width = int(aspect_ratio * large_size[1]) final_height = large_size[1] final_size = (final_width, final_height) imaged = im.resize((final_width, final_height), Image.ANTIALIAS) # imaged = ImageOps.fit(im, final_size, Image.ANTIALIAS, centering = (0.5,0.5)) imaged.save(large_file, "JPEG", quality=90) except IOError: errors.append('error while resizing image') if not errors: response = HttpResponse(json.dumps({'status': 'success','filename': filename }), mimetype="application/json") else: response = HttpResponse(json.dumps({'status': 'failure','errors': errors,'message': 'Error uploading Picture. '}), mimetype="application/json") return response else: return render(requests, 'upload.html') ``` Update : I was using Pillow to resize and compress my images. Even though the aspect ratio was maintained, there was a certain amount of dullness introduced in the images upon resizing [had more anti-aliasing than required as compared to original images]. I switched my processing library to ImageMagick(against numerous posts suggesting not to!) along with Wand API (docs.wand-py.org/en/0.3.7/index.html), to process my images. This change worked like a charm!

Original source

Related problems