2010-06-11 3 views
0

Я использовал этот небольшой фрагмент для выбора случайных изображений. Однако я хотел бы изменить его, чтобы выбрать только изображения определенного размера. У меня проблемы с проверкой размера изображения. Если я использую get_image_dimensions(), мне нужно использовать условный оператор, который затем требует, чтобы я допускал исключения. Итак, я думаю, мне нужны некоторые указатели, ограничивающие только размеры изображения. Благодарю.Как выбрать случайное изображение определенного размера с помощью Django/Python?

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 be 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) 

ответ

1

Ну, более прямой способ получить размеры изображения использует Python Imaging Library (который является тем, что использует Django для get_image_dimensions в бэкэнде в любом случае).

Таким образом, вы используете его как:

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

И ваш очень простое решение было бы что-то вроде:

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)) 

где my_dimensions есть - ваши размеры.

Проблема в том, что этот (как и любой другой метод, который проверяет размеры файла) фактически должен открывать и читать изображения каждый раз, что не умно для повторного использования. Поэтому, в зависимости от нагрузки вашего приложения, вы, вероятно, захотите поместить img_dimensions() в реальную отдельную функцию и запомните ее (http://code.activestate.com/recipes/52201-memoizing-cacheing-function-return-values/). Или, если это будет общей задачей, просто поместите изображения в папки, предварительно упорядоченные по размеру.

+0

Итак, когда я реализую это изменение, я получаю ошибку синтаксиса: «лямбда не может содержать присвоение». Кроме того, как делает это на самом деле отличается от чего-то вроде этого: имена файлов = [е для е в os.listdir (FULLPATH), если is_image_file (е) и get_image_dimensions (е) = my_dimensions] – Jonathan

+0

Doh! Должно быть: filenames = filter (lambda f: is_image_file (f) и img_dimensions (f) == my_dimensions, os.listdir (fullpath)). С двойным знаком равенства для сравнения вместо назначения. Что касается вашего второго вопроса, это просто стилистика - мне не нравятся длинные списки. – gilesc

Смежные вопросы