在Django中使用PIL两次调整图像大小

1 投票
3 回答
2958 浏览
提问于 2025-04-15 14:39

我有一个函数,想要从请求中获取的图片(request.FILES['image'])调整大小两次。我使用了image.thumbnail()这个方法,同时也用了Parser。第一次创建缩略图的时候一切都很顺利,但在我的视图中,如果我再重复一次相同的操作,就会在解析时出错,提示IOError无法解析图片。我感到很困惑。我尝试在内存中创建StringIO文件,而不是直接使用Django的UploadedFile对象,但结果还是一样。希望能得到一些帮助。

假设我想要做以下操作两次(使用两种不同的缩略图大小),而且不想两次都去获取URL:

import urllib2
from PIL import Image, ImageFile, ImageEnhance

# create Image instance
file = urllib2.urlopen(r'http://animals.nationalgeographic.com/staticfiles/NGS/Shared/StaticFiles/animals/images/primary/kemps-ridley-sea-turtle.jpg')
parser = ImageFile.Parser()
while True:
    s = file.read(1024)
    if not s:
        break
    parser.feed(s)
image = parser.close()

# make thumbnail
size = (75, 75)
image.thumbnail(size, Image.ANTIALIAS)
background = Image.new('RGBA', size, (255, 255, 255, 0))
background.paste(
    image,
    ((size[0] - image.size[0]) / 2, (size[1] - image.size[1]) / 2))

background.save('copy.jpg')

例如:

image = parser.close()
image2 = parser.close() # Obviously this doens't work
image2 = image # Obviously this doesn't either but you get what I need to do here
# Do 2 thumbnails with only one original source.

... 其他代码省略 ...

image.save('copy.jpg')
image2.save('copy.jpg')

3 个回答

0

我猜问题出在 image = parser.close() 这一行,可能是出现了 IOError 错误。所以很可能是 ImageFile 获取图像数据的方式出了问题。你有没有尝试过从本地文件读取呢?

如果解析器成功解码了一个图像,它会返回一个 Image 对象。否则,这个方法会抛出一个 IOError 异常。

来源.

2

比起复制原始图片,有一个更简单的办法,就是在每次调用 thumbnail(...) 之前,重置文件指针,像这样做:

original.seek(0)
2

如果你说的没错,这个图片能正常显示,那就没问题。其实有两种方法可以从一张图片中获取多个缩略图。

  1. 你可以使用PIL的 resize 方法,这个方法会返回一张调整大小后的图片。你只需要计算一下想要的尺寸,确保保持图片的比例不变。
  2. 使用 Image.copy() 方法来获取这张图片的副本。

像这样:

original = parser.close()
...

thumb1 = original.copy()
size = (75,75)
thumb1.thumbnail(size, Image.ANTIALIAS)
...

thumb2 = original.copy()
thumbnail2 = original.resize(size2, Image.ANTIALIAS)
...

这样做的话,原始图片不会被改变,你可以根据需要获取任意数量的副本。

撰写回答