2011-02-27 14 views
24

तो यह बहुत आसान होना चाहिए, फिर भी मैं इसे काम नहीं कर सकता।एक छवि प्रस्तुत करना

मेरे पास एक नियंत्रक विधि है जो एक क्वेरी के आधार पर एक छवि पाती है, तो आउटपुट कैश हो जाता है। छवि रिमोट (फ़्लिकर, Google छवियां, आदि) हो सकती है या यह स्थानीय हो सकती है। स्रोत के बावजूद, मुझे बस छवि फ़ाइल सामग्री लेने की आवश्यकता है, और इसे उपयोगकर्ता के पास भेज दें। संक्षेप में, एक प्रॉक्सी। दूरदराज के चित्रों के माध्यम से पासिंग ठीक से काम करने लगता है, लेकिन स्थानीय छवियों के माध्यम से गुजर एक मुझे देता है:

invalid byte sequence in UTF-8 

तो यहाँ मैं क्या मिला है। मुझे उम्मीद है कि कोई समस्या हल कर सकता है या मुझे मेरे कोड के साथ बेहतर दिशा में मार्गदर्शन कर सकता है।

def image_proxy 
    query = params[:query] 
    image_url = get_image_url(query) # returns an absolute local file path or a URL 

    response.headers['Cache-Control'] = "public, max-age=#{12.hours.to_i}" 
    response.headers['Content-Type'] = 'image/jpeg' 
    response.headers['Content-Disposition'] = 'inline' 
    render :text => open(image_url).read 
end 

दूरस्थ फ़ाइलें ठीक काम करती हैं, स्थानीय फाइलें नहीं होती हैं। किसी को

बोनस इस अन्य मुद्दे को हल मदद कर सकते हैं:

  1. मैं उचित सामग्री प्रकार सेट करना होगा। रिमोट इमेज यूआरएल मुझे छवि प्रकार नहीं बताती है, मुझे बस एक यूआरएल मिलता है और कभी-कभी यूआरएल में एक्सटेंशन नहीं होता है। इसलिए मैंने जेपीईजी चुना क्योंकि ऐसा लगता है कि मुझे भेजे गए छवि प्रकार के बावजूद यह काम करता है।

धन्यवाद!

उत्तर

23

render :text => open(image_url, "rb").read का उपयोग करने का प्रयास करें, जो रूबी को बताता है कि जो फ़ाइल खुलती है वह द्विआधारी है, और इसे पाठ के रूप में पढ़ने की कोशिश नहीं करना है।

संपादित

बोनस प्रश्न के लिए, आप पहले कुछ बाइट्स पढ़ सकते हैं और वे क्या होते हैं पर दिखाई दे सकता है। एक पीएनजी हमेशा हेक्साडेसिमल बाइट मान 89 50 4E 47 0 डी 0 ए 1 ए 0 ए (या दशमलव मान 137 80 78 71 13 10 26 10) से शुरू होगा।

विकिपीडिया में list of magic numbers used to identify file है जिसे आप देख सकते हैं। बस कुछ प्रकार की एक विधि बनाएं जो पहले कुछ बाइट्स को पढ़ती है और इसकी तुलना करता है।

+0

ग्रेट उत्तर, पूरी तरह से काम किया। –

14

रेल का कौन सा संस्करण? रेल 3 के लिए, आपको streaming methods को जोड़ा जाना चाहिए जो जोड़ा गया था। send_data बाइनरी डेटा भेजने का सही तरीका होगा। यदि छवियां स्थानीय हैं, और आपका वेब सर्वर इसका समर्थन करता है, तो आप send_file का उपयोग कर सकते हैं जो उपयोगकर्ता को छवि डाउनलोड करते समय रेल उदाहरण को अवरुद्ध नहीं करेगा।

+1

हां, 'send_data' वह है जो आप चाहते हैं, 'रेंडर' नहीं। – aceofspades

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