Python/Django从URL下载图像,修改并保存到ImageField

Joe*_*e J 10 python django file urllib2 python-imaging-library

我一直在寻找一种从URL下载图像,在其上执行一些图像处理(调整大小)动作,然后将其保存到django ImageField的方法.使用两个很棒的帖子(下面链接),我已经能够下载图像并将其保存到ImageField.但是,一旦我拥有它,我一直在操作文件时遇到一些麻烦.

具体来说,模型字段save()方法需要File()对象作为第二个参数.所以我的数据最终必须是一个File()对象.下面链接的博客文章显示了如何使用urllib2将图像URL保存到File()对象中.这很好,但是,我还想使用PIL作为Image()对象来操作图像.(或ImageFile对象).

我首选的方法是将图像URL直接加载到Image()对象中,预先形成resize,然后将其转换为File()对象,然后将其保存在模型中.但是,我将Image()转换为File()的尝试失败了.如果可能的话,我想限制我写入磁盘的次数,所以我想在内存中使用这个对象转换或使用NamedTemporaryFile(delete = True)对象,所以我不必担心周围的额外文件.(当然,我希望通过模型保存文件后将文件写入磁盘).

import urllib2
from PIL import Image, ImageFile    
from django.core.files import File
from django.core.files.temp import NamedTemporaryFile

inStream = urllib2.urlopen('http://www.google.com/intl/en_ALL/images/srpr/logo1w.png')

parser = ImageFile.Parser()
while True:
    s = inStream.read(1024)
    if not s:
        break
    parser.feed(s)

inImage = parser.close()
# convert to RGB to avoid error with png and tiffs
if inImage.mode != "RGB":
    inImage = inImage.convert("RGB")

# resize could occur here

# START OF CODE THAT DOES NOT SEEM TO WORK
# I need to somehow convert an image .....

img_temp = NamedTemporaryFile(delete=True)
img_temp.write(inImage.tostring())
img_temp.flush()

file_object = File(img_temp)

# .... into a file that the Django object will accept. 
# END OF CODE THAT DOES NOT SEEM TO WORK

my_model_instance.image.save(
         'some_filename',
         file_object,  # this must be a File() object
         save=True,
         )
Run Code Online (Sandbox Code Playgroud)

使用此方法,每当我将其视为图像时,该文件都会显示为损坏.有没有人有任何从URL获取文件文件的方法,允许人们将其作为图像操作,然后将其保存到Django ImageField?

任何帮助深表感谢.

以编程方式将图像保存到Django ImageField

Django:从图像url在ImageField中添加图像

更新08/11/2010:我最终使用StringIO,但是,当我尝试将其保存在Django ImageField中时,我发现了一个异常的异常.具体来说,堆栈跟踪显示名称错误:

"AttribueError exception "StringIO instance has no attribute 'name'"
Run Code Online (Sandbox Code Playgroud)

在挖掘Django源代码之后,当模型保存尝试访问StringIO"File"的size属性时,看起来会出现此错误.(虽然上面的错误表明名称有问题,但此错误的根本原因似乎是StringIO图像上缺少size属性).只要我为图像文件的size属性赋值,它就可以正常工作.

Wol*_*lph 5

试图用 1 块石头杀死 2 只鸟。为什么不使用 (c)StringIO 对象而不是 NamedTemporaryFile?您不必再将它存储在磁盘上,而且我知道这样的事情是有效的(我自己使用类似的代码)。

from cStringIO import StringIO
img_temp = StringIO()
inImage.save(img_temp, 'PNG')
img_temp.seek(0)

file_object = File(img_temp, filename)
Run Code Online (Sandbox Code Playgroud)