Chris May
Chris May

Reputation: 582

Python 2 / Pillow - issue calculating resized image height & width

I'm building a blog-style website using Django that allows people to upload images for their posts. I wrote some code to resize user uploaded images. It takes the uploaded image and saves two copies, 1 scaled down large image and 1 thumbnail.

The code works perfectly on my personal computer I'm using for development (Python 3, Django 1.8), but it doesn't work in production on my server (Python 2, Django 1.8). On the server, it appears the image resize math is giving a value of 0 for either the width or height. I've tried various methods of rounding, etc but nothing seems to fix the issue.

Here's the section of my views.py that handles the image:

    (card_image_resize, card_image_thumb_resize, card_image_orientation) = image_resize(card_image.userimg.path)
    (w, h) = card_image_resize.size
    card_image_resize.save(card_image.userimg.path)
    card_image_thumb_resize.save(card_image.userimg_thumb.path)
    card_image.orientation = card_image_orientation
    card_image.save()

And here's the image resize code:

def image_resize(path):
    image = Image.open(path)

    (w, h) = image.size
    if w > h:
        orientation = 'l'
    elif w < h:
        orientation = 'p'
    else:
        orientation = 's'

#calculate new large image dimensions
    if w >= 1000 or h >= 1000:
        if w > h:
            w_new = 1000
            h_new = (h/w) * 1000
        elif h > w:
            h_new = 1000
            w_new = (w/h) * 1000
        elif h == w:
            h_new = 1000
            w_new = 1000
    else:
        if w > h:
            w_new = 400
            h_new = (h/w) * 400
        elif h > w:
            h_new = 400
            w_new = (w/h) * 400
        elif h == w:
            h_new = 400
            w_new = 400

#calculate thumbnail dimensions
    if w >= 1000 or h >= 1000:
        if w > h:
            wthumb_new = 400
            hthumb_new = (h/w) * 400
        elif h > w:
            hthumb_new = 400
            wthumb_new = (w/h) * 400
        elif h == w:
            hthumb_new = 400
            wthumb_new = 400

    w_new = int(w_new)
    h_new = int(h_new)
    try:
        wthumb_new = int(wthumb_new)
        hthumb_new = int(hthumb_new)
        image_thumb = image.resize((wthumb_new, hthumb_new), Image.ANTIALIAS)
        image = image.resize((w_new, h_new), Image.ANTIALIAS)
    except:
        image_thumb = image.resize((w, h), Image.ANTIALIAS)

    image = image.resize((w_new, h_new), Image.ANTIALIAS)

    return image, image_thumb, orientation

The part that's causing the issue (I assume) is the section the calculates the ratio calculation for height or width: w_new = (w/h) * 1000. When I run this in development, I'm getting the error Exception Value: tile cannot extend outside image. Looking at the image size values, it's clear that the w_new / h_new calculation is returning zero:

card_image_resize: PIL.Image.Image image mode=RGB size=1000x0 at 0x7FADB1A0E320

The error occurs upon saving

card_image.save()

My question is why and how do I get around this? It seems like a pretty straightforward formula to maintain the image size ratio. Even stranger that it works with Python 3 but not Python 2.

I'm admittedly not an expert at this, so I'm open to a more efficient way of resizing the image. However, I'd still be interested to learn why that formula returns a value of zero.

Upvotes: 0

Views: 307

Answers (1)

TigerhawkT3
TigerhawkT3

Reputation: 49318

In Python 3, / uses floating-point arithmetic when necessary. In Python 2, you have to specify floats. Change:

(w/h) * 400

to

(float(w)/h) * 400

and similar, wherever necessary.

Upvotes: 1

Related Questions