如何使用Django/Python选择特定大小的随机图片?

0 投票
1 回答
909 浏览
提问于 2025-04-15 23:52

我一直在用这段小代码来随机选择图片。不过,我想改成只选择特定大小的图片。现在我在检查图片大小时遇到了麻烦。如果我使用get_image_dimensions()这个函数,就需要用到条件语句,这样就得处理一些例外情况。所以,我想请教一下,怎么才能简单地限制图片的尺寸。谢谢。

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 个回答

1

其实,获取图片尺寸有个更直接的方法,就是使用Python图像库(Django在后台也是用这个库来获取图片尺寸的)。

你可以这样使用它:

>> 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/)。或者如果这个操作会很常见,干脆把图片按尺寸预先放到不同的文件夹里。

撰写回答