2009-08-28 9 views
5

में छवि को स्ट्रीमिंग बाइट [] में मेरे पास मेरे उपयोगकर्ता डेटा के साथ संग्रहीत एक SQL छवि डेटाबेस में संग्रहीत एक छवि है जिसे मैं एक बार में पुनर्प्राप्त करता हूं।एएसपी.NET सी #

अब मेरे पास बाइट [] सीधे उस पृष्ठ पर है जिसे मैं इसे दिखाना चाहता हूं। मैं इसे अपने वेबकंट्रोल में कैसे रखूं। इमेज? मैं एक HttpHandler को कॉल नहीं करना चाहता और डेटाबेस को फिर से कॉल करना चाहता हूं।

यह स्पष्ट रूप से पूरे पृष्ठ पर इसे आउटपुट करता है।

  Context.Response.BinaryWrite(user.Picture.ToArray()); 
+0

क्या आप छवि डेटा को फ़ाइल के रूप में स्टोर नहीं कर सकते? – AnthonyWJones

+0

यह पहला मार्ग था, लेकिन डेटाबेस में छवि को स्टोर करना पसंदीदा समाधान था। (मेरे सिर के ऊपर) तो मुझे स्थिति से सबसे अच्छा बनाना है। – markoo

+0

सभी की मदद के लिए धन्यवाद। त्वरित और अंतर्दृष्टि जवाब। – markoo

उत्तर

4

यदि यह एक छोटी छवि है तो आप इसे बेस -64 एन्कोडेड डेटा के रूप में एक छवि-टैग में आउटपुट करेंगे। See here for a similar situation

लेकिन 99.9% सभी परिस्थितियों में आप एक HttpHandler बनायेंगे जो छवि को वापस लाएगा। यह मुझे लगता है कि यह करने का सबसे आसान और सबसे तेज़ तरीका है।

+0

यह वही था जो मैं ढूंढ रहा था। छवि एक छोटा 180 x 160 पीएक्स जीआईएफ/जेपीईजी है। यह इस तरह समाप्त हुआ: बाइट [] picByteArray = user.Picture.ToArray(); स्ट्रिंग myPicString = कनवर्ट करें। ToBase64String (picByteArray); myPicture.Attributes ["src"] = "डेटा: छवि/gif; base64," + myPicString; – markoo

+0

@ मार्कू: बेस 64 एन्कोड किए जाने पर कितने बाइट्स समाप्त होते हैं? छवि डेटा को सीधे द्विपक्षीय रूप से जेनरेट किए गए HTML में रखकर आपको क्लाइंट को हर बार लाने की आवश्यकता होती है, यह तब तक कैश करने योग्य नहीं है जब तक आप संपूर्ण HTML प्रतिक्रिया कैशेबल नहीं बनाते। – AnthonyWJones

+0

मेरी छवि लगभग 8 केबी होने के समाप्त होती है, जो मेरे साधारण उपयोगकर्ता डेटा दृश्य में काफी स्वीकार्य है। यह मेरी कंपनी के भीतर एक "आंतरिक" व्यवस्थापक साइट है। हालांकि वास्तविक घटक बाहरी रूप से उपयोग किया जाएगा। इन बाहरी घटकों और साइटों को हमारे व्यवस्थापक द्वारा भारी कैश किया जाता है। तो मुझे इस समाधान को लागू करने में कोई चिंता नहीं है। ये प्रोफाइल बहुत सीमित हैं। घर पत्रकारों में केवल 20 या 30। तो यह सिर्फ इनके लिए एक अलग छवि तालिका रखने के लिए overkill लग रहा था। आपकी अंतर्दृष्टि के लिए फिर से धन्यवाद। – markoo

0

अलग पृष्ठ है जहाँ आप उदाहरण के लिए छवि बनाएगा बनाएँ: image.aspx और अन्य पृष्ठों पर इसका इस्तेमाल

<img src="image.aspx?id=number" > 

संख्या डेटाबेस में छवि के आईडी है

+0

छवियों को आउटपुट करने के लिए एएसपीएक्स का उपयोग न करें, एएसएक्स का उपयोग करें। – AnthonyWJones

+0

@ एंथनी: ओपी का कहना है कि वे 'एशक्स' का उपयोग नहीं करना चाहते हैं, हालांकि मैं मानता हूं कि ऐसा करने का यह सही तरीका है। (और 'aspx' बनाना किसी भी तरह से' ashx' बनाने से आसान नहीं है!) – LukeH

+0

@ एंथनी: मुझे भिन्नता पता नहीं है। यह केवल विस्तार नहीं है? यह रूटिंग के साथ भी संख्या.जेपीजी हो सकता है। –

1

लपेटें बाइट सरणी मेमोरीस्ट्रीम ऑब्जेक्ट में और एएसपी.NETs कैश में रखें।

MemoryStream ms = new MemoryStream(user.Picture.ToArray()); 
Guid imageGuid = new Guid(); 
HttpRuntime.Cache.Add(imageGuid.ToString(), ms, null, 
    DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null); 

फिर कैश से बाहर लाने और इसे ग्राहक को भेजने के लिए एक हैंडलर (.ashx) का उपयोग करें।

string imageGuid = context.Request.QueryString[image]; 
MemoryStream ms = (MemoryStream)HttpRuntime.Cache[imageGuid]; 
// configure context.Response with appropriate content type and cache settings 

// ** Edit ** 
// It seems I need to be more explicit with regard to the above comment:- 
context.Response.Cache.SetCacheability(HttpCacheability.Public); 
context.Response.Cache.SetLastModified(DateTime.UtcNow); 
context.Response.Cache.SetExpires(DateTime.UtcNow.AddHours(2); 
context.Response.Cache.SetMaxAge(TimeSpan.FromHours(2)); 
context.Response.Cache.SetValidUntilExpires(true); 

ms.WriteTo(context.Response.OutputStream); 

अब आप मेमोरीस्ट्रीम को कैश से छोड़ सकते हैं।

HttpRuntime.Cache.Remove(imageGuid); 
+0

यह एक वेबफर्म पर स्केल नहीं करेगा (जब तक कि आपके पास कुछ प्रकार का वितरित कैश न हो)। – LukeH

+0

कभी भी ऐसा न करें। आप HTTP की सभी भलाई ('अगर संशोधित-चूंकि', कैशिंग, आदि) और पूरी तरह से लाभ के लिए स्केलेबिलिटी का त्याग कर रहे हैं। –

+0

@ सैंटन: क्या आपने मेरे कोड में टिप्पणी की रेखा देखी है? आपको क्या लगता है कि मेरा मतलब है? – AnthonyWJones

0

आप एक IHttpHander जो छवि बाइट्स लिखेंगे और उचित Content-Type एक प्रतिक्रिया स्ट्रीम की जरूरत है। this, this और this देखें।

+0

आप प्रश्न में बिंदु से चूक गए हैं। यह देखते हुए कि आपके पास निष्पादन एएसपीएक्स पृष्ठ में डेटाबेस से प्राप्त छवि डेटा की एक बाइट सरणी है, तो आप उस छवि को डीबी के दोबारा पूछे बिना उस छवि को प्रदर्शित करने के लिए आउटपुट में ' AnthonyWJones

+0

@ एंथनी: निश्चित रूप से बिंदु यह है कि उसे पृष्ठ पर डेटाबेस से छवि डेटा खींचने की आवश्यकता नहीं है। उसे * पुनः क्वेरी * डेटाबेस की आवश्यकता नहीं है - उसे उचित स्थान/समय (यानी, एक अलग 'एशक्स' हैंडलर में) एक बार * क्वेरी करने की आवश्यकता है। – LukeH

+0

@Luke: यह हो सकता है, लेकिन हम पता नहीं है कि हम करते हैं? हमारे पास इस सवाल से है कि किसी कारण से उसके पास एक वस्तु है जिसमें पहले से ही एक लोड ऑब्जेक्ट है। शायद इसे बेहतर से बचा जा सकता है फिर भी तस्वीर को फाइल सिस्टम में रखें। मैं हाथ में सवाल का जवाब देना पसंद करता हूं, खासकर जब से कुछ अन्य SO उपयोगकर्ता किसी बिंदु पर पा सकते हैं क्योंकि वे इस स्थिति में अपरिहार्य कारणों से हैं। – AnthonyWJones

0

मुझे पूरा यकीन है कि आप इसे पृष्ठ में ही नहीं कर सकते हैं।

यदि आप छवि को आउटपुट करने के लिए HTTP हैंडलर बनाना नहीं चाहते हैं तो आपका विकल्प अलग aspx पृष्ठ बनाना है। अपने img टैग के src को उस पृष्ठ पर इंगित करने के लिए, क्वेरीस्ट्रिंग में किसी प्रकार की आईडी को पास करने के लिए सेट करें ताकि छवि डेटा डेटाबेस से खींचा जा सके।

ऐसा करने के बाद, aspx पृष्ठ स्थापित करने के लिए यह ashx स्थापित करने से कोई तेज़ या आसान नहीं है। मैं इसे सही तरीके से करने और HTTP हैंडलर बनाने की अनुशंसा करता हूं।

+0

मेरे पास पहले से ही डेटाबेस से डेटा है। मैं एक और कॉल सहेजना चाहता हूं। – markoo