开发者

How to select random image of specific size using Django / Python?

I've been using this little snippet to select random images. However I would like to change it to select only images of a certain size. I'm running into trouble checking against image size. If I use get_image_dimensions() I need to use a conditional statement, which then requires that I allow exceptions. So, I guess I need some pointers on just limiting by image dimensions. Thanks.

import os
import random
import posixpath
from django import template
from django.conf import settings

register = template.Library()

def is_image_file(filename):
    """Does `filename` appear to b开发者_Python百科e an image file?"""
    img_types = [".jpg", ".jpeg", ".png", ".gif"]
    ext = os.path.splitext(filename)[1]
    return ext in img_types

@register.simple_tag
def random_image(path):
    """
    Select a random image file from the provided directory
    and return its href. `path` should be relative to MEDIA_ROOT.

    Usage:  <img src='{% random_image "images/whatever/" %}'>
    """
    fullpath = os.path.join(settings.MEDIA_ROOT, path)
    filenames = [f for f in os.listdir(fullpath) if is_image_file(f)]
    pick = random.choice(filenames)
    return posixpath.join(settings.MEDIA_URL, path, pick)


Well, a more direct way to get image dimensions is using the Python Imaging Library (which is what Django uses for get_image_dimensions in the backend anyway).

So, you use it like:

>> import Image
>> img = Image.open("foo.png")
>> img.size
(1729,828)

And your very simplest solution would be something like:

img_dimensions = lambda f: Image.open(f).size
filenames = filter(lambda f: is_image_file(f) and img_dimensions(f)==my_dimensions, os.listdir(fullpath))

where my_dimensions are -- your dimensions.

Problem is, that this (as well as any other method that checks file dimensions) actually has to open and read the images each time, which is not smart to do repeatedly. So depending on the load of your application, you will probably want to put img_dimensions() into a real, separate function and memoize it (http://code.activestate.com/recipes/52201-memoizing-cacheing-function-return-values/). Or if this is going to be a common task, just put images into folders pre-ordered by dimensions.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜