2010-08-10 5 views
10

URL에서 이미지를 다운로드하고 이미지 조작 (크기 조정) 작업을 수행 한 다음 이미지를 저장하는 방법을 찾고있었습니다. django ImageField. 아래에 링크 된 두 개의 위대한 게시물을 사용하여 이미지를 다운로드하여 ImageField에 저장할 수있었습니다. 그러나 일단 파일을 가지고 있으면 파일 조작에 어려움을 겪고 있습니다.Python/Django에서 이미지를 다운로드하고 수정하고 ImageField에 저장

특히 model 필드 save() 메서드에는 두 번째 매개 변수로 File() 개체가 필요합니다. 그래서 내 데이터는 결국 File() 객체가되어야합니다. 아래 링크 된 블로그 게시물은 urllib2를 사용하여 이미지 URL을 File() 객체에 저장하는 방법을 보여줍니다. 이것은 훌륭하지만 PIL을 Image() 객체로 사용하여 이미지를 조작하고 싶습니다. (또는 ImageFile 객체).

선호하는 방법은 이미지 URL을 Image() 객체에 직접로드하고 크기 조정을 수행 한 다음 File() 객체로 변환 한 다음 모델에 저장하는 것입니다. 그러나 Image()를 File()로 변환하려는 시도가 실패했습니다. 가능하다면 디스크에 쓰는 횟수를 제한하고 싶습니다. 따라서 Memory에서이 객체 변환을 수행하거나 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, 
     ) 

이 방법을 사용하면 이미지로 볼 때마다 파일이 손상됩니다. 누구든지 URL에서 파일 파일을 가져 와서 이미지로 조작 한 다음 장고 ImageField에 저장할 수있는 방법이 있습니까?

도움을 주시면 감사하겠습니다.

Programmatically saving image to Django ImageField

Django: add image in an ImageField from image url

업데이트 2010년 8월 11일 : 나는 그러나, 내가 장고 ImageField에 저장하려고 할 때 stringIO는 특별한 예외를 던지고 있었다 StringIO로가는 결국 않았다. 특히, 스택 추적은 이름 오류 보여 : 시도 저장 모델이 StringIO "파일"의 크기 속성에 액세스 할 때이 오류가 발생하는 것처럼 장고 소스를 통해 파고 후

"AttribueError exception "StringIO instance has no attribute 'name'" 

을 것 같습니다. (위의 오류는 이름에 문제가 있음을 나타내지 만이 오류의 근본 원인은 StringIO 이미지의 크기 속성이 부족한 것 같습니다.) 이미지 파일의 size 속성에 값을 할당하자마자 제대로 작동했습니다.

+0

또한 StringIO를 사용하여 이미지를 메모리에 저장 한 다음 File.open()을 사용하여 읽었지만 그와 관련된 몇 가지 문제가있었습니다. –

답변

4

1 개의 돌로 2 마리의 새를 죽이려는 시도입니다. 왜 NamedTemporaryFile 대신에 (c) StringIO 객체를 사용합니까? 더 이상 디스크에 저장할 필요가 없으며이 기능이 작동한다는 사실을 알고 있습니다 (비슷한 코드를 직접 사용합니다).

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

file_object = File(img_temp, filename) 
+0

감사합니다. 도와 주셔서 감사합니다. 나는 당신의 해결책을 시도했지만 여전히 그것에 문제가 있습니다. 특히 마지막에 save()를 호출하면 AttribueError 예외가 발생합니다. "StringIO 인스턴스에 'name'속성이 없습니다." ------------------ img_temp = StringIO .StringIO(); inImage.save (img_temp, format = 'PNG'); img_temp.seek (0); –

+1

@ Joe J :'StringIO'를 사용할 때'filename' 인수는 강제적입니다. 그게 지금 당장 당신 문제예요.) – Wolph

+0

WoLpH. 파일 이름이 파일 시스템의 경로와 일치해야합니까? 아니면 임시 파일의 이름이 임의로 구성되어있을 수 있습니까? –

관련 문제