动态创建图像缩略图(使用django)

8
我希望能够根据URL参数动态创建缩略图。例如,http://mysite.com/images/1234/120x45.jpg将为图像ID 1234 创建一个 120x45 的缩略图。
显而易见的解决方案是拥有一个Django视图,它执行以下操作:
  1. 查找先前缓存的此大小的图像版本。
  2. 如果没有缓存,则创建一个缩略图(一些逻辑用于锁定,以便只有1个进程创建缩略图,其他进程等待)。
  3. 通过Django传输结果。
这应该“有效”,但我担心性能问题。我不喜欢使用Django来提供静态内容。还有其他方法可以解决这个问题吗?

如果您正在动态创建缩略图,那么它就不是静态的了,对吧? - Blair Conrad
我认为它是一种惰性加载的静态缩略图。一旦创建,我希望其具有与静态相同的性能。 - Gattster
10个回答

8
您不必使用Django直接提供静态内容。只需让您的服务器将图像文件夹的404请求路由到Django视图,其中拆分文件名并生成适当的缩略图,然后重定向回原始URL(希望它不再是404)即可。
至于其他答案中的django-imagekit建议,我不确定它是否可以让您基于URL动态生成图像缩略图,但我确实建议您使用它的所有功能。
关于实际的URL结构,我认为更典型的/images/filename-120x45.jpg会更容易过滤掉与动态缩略图生成无关的404请求。例如,假设有大量/images/original_size_image.jpg的404错误。您不希望这些被路由到Django,并且只能使用正则表达式匹配该格式的文件名。
你需要小心,不要让任何人知道这个功能并在你的Django应用程序中滥用它。他们可能会使用无限数量的图像大小和文件名组合来破坏它。你需要想办法对这些请求设置上限,比如如果任一维度大于原始尺寸,则重定向回404,甚至可以想办法限制同一图像的多个维度的请求。也许当你提到“锁定”时,这就是你所想的。
另外,我看到你标记了Apache,但我真的很想建议你通过Nginx之类的东西提供静态内容。如果你使用一个不完全垃圾的静态文件服务器来提供静态文件,你或许可以消除动态图像请求的额外开销。

很好的答案。解决垃圾邮件问题的一种方法是有一个预定义的允许使用的图像/缩略图大小列表。此外,我同意使用nginx。我目前正在使用nginx提供静态内容,并将在此问题中添加nginx标签。 - Gattster
啊,是的...但我不确定预定义的允许大小列表对您有多“动态”,所以我没有提到它。我也不确定您的图像格式是否一致或标准比例,或者如果您打算裁剪缩略图,如果它不适合预定义的大小等等。此外,我将立即编辑我的答案,以添加关于您讨论的URL格式的内容。 - user136565
我正在使用Bottle,但是使用相同的原理它也可以工作。以这种方式工作真的很酷。 - Richard Nienaber

5

4

看这个应用可以生成缩略图。

该应用使用Python编写,使用tornadoweb服务器。

https://github.com/globocom/thumbor

pip install thumbor

优秀的应用程序


Thumbor确实可以满足原帖作者的所有需求。 - Maik Hoepfel

2

我查阅了这些答案,虽然它们可用,但对我来说过于复杂。如果你只想快速简单地获取缩略图,只使用PIL库可能是个不错的选择,以下是我的代码:

file, ext = os.path.splitext('image.jpg')
im = Image.open('/full/path/to/image.jpg')
im.thumbnail(size, Image.ANTIALIAS)
thumb_path = os.path.join('/full/path/to/thumb/dir/', file + ".thumb" + ".jpeg")
im.save(thumb_path)

在这里下载PIL库 链接

祝愿能对某些人有所帮助。



2
你可以看一下sorl-thumbnail文档。我在几乎所有的项目中都会使用它,还会与Nginx一起提供/media/目录下的静态内容 :)

0

0

只包含链接的答案被认为是不好的做法。请在此总结内容(不要复制/粘贴),以便答案可以独立存在。如果您不这样做,您的答案可能会被删除,特别是如果链接失效。 - Martijn Pieters

0

你可能只需要根据需求指定的尺寸来调整显示的图像大小。

Django Imagefit库正是这样做的,它还提供了裁剪的可能性。

在你的例子中,你可以写成{{ 'http://example.com/images/1234.jpg'|resize:'120x45' }},然后你就会得到一个大小为120x45的图像。


0

我曾经遇到过完全相同的问题:在高流量网站上,在响应时间内生成数十个缩略图是不可行的,而批量为所有过去的内容生成缩略图也是不现实的,因此我创建了一个应用程序来解决这个问题。请查看:https://github.com/hcarvalhoalves/django-rest-thumbnails


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接