2010-08-10 15 views
10

पर छवि डाउनलोड करें मैं एक यूआरएल से एक छवि डाउनलोड करने का एक तरीका ढूंढ रहा हूं, उस पर कुछ छवि कुशलता (आकार बदलें) क्रियाओं को पूर्ववत करता हूं, और फिर इसे सहेजता हूं django ImageField। दो महान पदों (नीचे लिंक) का उपयोग करके, मैं एक छविफाइल पर एक छवि को डाउनलोड और सहेजने में सक्षम हूं। हालांकि, मुझे एक बार फ़ाइल में हेरफेर करने में कुछ परेशानी हो रही है।पायथन/Django डाउनलोड छवि से छवि, संशोधित, और छविफाइल

विशेष रूप से, मॉडल फ़ील्ड सेव() विधि को फ़ाइल पैरामीटर() ऑब्जेक्ट को दूसरे पैरामीटर के रूप में आवश्यक है। तो मेरा डेटा अंत में एक फ़ाइल() वस्तु होना है। नीचे दिए गए ब्लॉग पोस्ट से पता चलता है कि एक छवि URL को फ़ाइल() ऑब्जेक्ट में सहेजने के लिए urllib2 का उपयोग कैसे करें। यह बहुत अच्छा है, हालांकि, मैं छवि को (छवि) के रूप में पीआईएल का उपयोग करके छवि में हेरफेर करना चाहता हूं। (या ImageFile ऑब्जेक्ट)।

मेरा पसंदीदा दृष्टिकोण छवि छवि को सीधे छवि() ऑब्जेक्ट में लोड करने, आकार बदलने से पहले, और इसे फ़ाइल() ऑब्जेक्ट में परिवर्तित करने और फिर मॉडल में सहेजने के लिए होगा। हालांकि, एक छवि() को एक फ़ाइल() में कनवर्ट करने के मेरे प्रयास विफल हो गए हैं। यदि संभव हो, तो मैं डिस्क पर लिखने की संख्या को सीमित करना चाहता हूं, इसलिए मैं मेमोरी में इस ऑब्जेक्ट रूपांतरण को करना चाहता हूं या नामांकित समकालीन फ़ाइल (हटाएं = सही) ऑब्जेक्ट का उपयोग करना चाहता हूं इसलिए मुझे चिंता करने की ज़रूरत नहीं है चारों ओर बिछाने अतिरिक्त फाइलें। (बेशक, मैं चाहता हूं कि मॉडल को मॉडल के माध्यम से सहेजने के बाद फ़ाइल को डिस्क पर लिखा जाए)।

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 से फ़ाइल फ़ाइल लेता है, किसी को इसे एक छवि के रूप में उपयोग करने की अनुमति देता है और फिर इसे Django ImageField में सहेजता है?

किसी भी मदद की बहुत सराहना की जाती है।

Programmatically saving image to Django ImageField

Django: add image in an ImageField from image url

अद्यतन 2010/08/11: मैं StringIO के साथ जा रहा अंत था, हालांकि, मैं stringIO एक असामान्य अपवाद फेंक रहा था जब मैं एक Django ImageField में सहेजने की कोशिश की। विशेष रूप से, स्टैक ट्रेस एक नाम त्रुटि से पता चला है:

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

Django स्रोत के माध्यम से खुदाई करने के बाद, ऐसा लगता है कि इस त्रुटि की तरह जब मॉडल की कोशिश करता बचाने StringIO "फ़ाइल" के आकार विशेषता का उपयोग करने के कारण होता था। (हालांकि उपरोक्त त्रुटि नाम के साथ एक समस्या का संकेत देती है, इस त्रुटि का मूल कारण स्ट्रिंगियो छवि पर आकार संपत्ति की कमी प्रतीत होता है)। जैसे ही मैंने छवि फ़ाइल के आकार विशेषता के लिए एक मान असाइन किया, यह ठीक काम किया।

+0

मैंने छवि को स्मृति में सहेजने के लिए स्ट्रिंगियो का भी उपयोग किया है और फिर इसे File.open() के साथ पढ़ा है लेकिन इसके साथ कुछ समस्याएं भी हैं। –

उत्तर

4

1 पत्थर के साथ 2 पक्षियों को मारने के प्रयास में। नामांकित समकालीन फ़ाइल के बजाय एक (सी) स्ट्रिंगियो ऑब्जेक्ट का उपयोग क्यों न करें? आपको इसे डिस्क पर अब स्टोर नहीं करना होगा और मुझे इस तथ्य के बारे में पता है कि इस तरह कुछ काम करता है (मैं खुद को समान कोड का उपयोग करता हूं)।

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

file_object = File(img_temp, filename) 
+0

धन्यवाद WoLpH, मैं आपकी मदद की सराहना करता हूं। मैंने आपके समाधान की कोशिश की लेकिन मुझे अभी भी कुछ परेशानी है। विशेष रूप से, जब मैं अंत में सेव() को कॉल करता हूं तो मुझे AttribueError अपवाद मिलता है "स्ट्रिंगियो इंस्टेंस में कोई विशेषता नहीं है 'नाम' ------------------ img_temp = स्ट्रिंगियो .StringIO(); inImage.save (img_temp, format = 'PNG'); img_temp.seek (0); –

+1

@ जो जे: 'स्ट्रिंगियो' का उपयोग करते समय 'फ़ाइल नाम' तर्क अनिवार्य है। यह अभी आपकी समस्या है;) – Wolph

+0

धन्यवाद फिर से WoLpH। क्या फ़ाइल नाम को फाइल सिस्टम पर पथ से मेल खाना पड़ेगा या क्या यह अस्थायी फ़ाइल के लिए कुछ यादृच्छिक नाम हो सकता है? –

संबंधित मुद्दे