2009-02-24 16 views
7

मूल रूप से मैं एक ASP.NET हैंडलर में एक सरल छवि प्रस्तुत करने के लिए कोशिश कर रहा हूँ:करने के लिए छवि प्रस्तुत करना नहीं कर सकते HttpContext.Response.OutputStream

public void ProcessRequest (HttpContext context) 
{ 
    Bitmap image = new Bitmap(16, 16); 
    Graphics graph = Graphics.FromImage(image); 

    graph.FillEllipse(Brushes.Green, 0, 0, 16, 16); 

    context.Response.ContentType = "image/png"; 
    image.Save(context.Response.OutputStream, ImageFormat.Png); 
} 

लेकिन मैं निम्न अपवाद प्राप्त करें:

System.Runtime.InteropServices.ExternalException: A generic error 
occurred in GDI+. 
    at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, 
    EncoderParameters encoderParams) 

समाधान आउटपुटस्ट्रीम पर छवि लिखने के बजाय इसका उपयोग करना है:

MemoryStream temp = new MemoryStream(); 
image.Save(temp, ImageFormat.Png); 
byte[] buffer = temp.GetBuffer(); 
context.Response.OutputStream.Write(buffer, 0, buffer.Length); 

तो मैं बस उत्सुक हूं क्यों पहला संस्करण समस्याग्रस्त है?

संपादित करें: HRESULT 80004005 है जो केवल "सामान्य" है।

+0

अपने समाधान पर GetBuffer() का उपयोग कर, चाहिए आप 'Response.OutputStream.Write' के बाद 'छवि' और 'मेमोरीस्ट्रीम' ऑब्जेक्ट दोनों का निपटान करते हैं? – Pingpong

उत्तर

6

लेखक को वास्तव में स्ट्रीम में लिखने की आवश्यकता है।

लेकिन अपने अंतिम स्रोत कोड में, सुनिश्चित करें कि आप उचित डेटा प्राप्त करने के लिए मेमोरीस्ट्रीम.ToArray() का उपयोग करते हैं या यदि आप डेटा कॉपी नहीं करना चाहते हैं, तो MemoryStream.GetBuffer() को MemoryStream.Length के साथ उपयोग करें और लौटा सरणी की लंबाई नहीं।

गेटबफर मेमोरीस्ट्रीम द्वारा उपयोग किए जाने वाले आंतरिक बफर को वापस कर देगा, और इसकी लंबाई आमतौर पर स्ट्रीम में लिखे गए डेटा की लंबाई से अधिक होगी।

यह आपको स्ट्रीम के अंत में कचरा भेजने से बचाएगा, और कुछ सख्त छवि डिकोडर को गड़बड़ नहीं करेगा जो पिछली कचरा बर्दाश्त नहीं करेगा। (और कम डेटा स्थानांतरित करें ...)

+0

अच्छा पकड़, धन्यवाद! एमएसडीएन का कहना है कि GetBuffer(): http://msdn.microsoft.com/en-us/library/system.io.memorystream.getbuffer.aspx के बारे में बहुत कुछ वही बात है – Serguei

1

मुझे विश्वास है कि समस्या यह है कि Response.OutputStream मांग का समर्थन नहीं करता है। एक पीएनजी (या जेपीईजी) को बचाने के लिए, छवि ऑब्जेक्ट को अनुक्रमिक रूप से आउटपुट लिखने में सक्षम होना चाहिए। अगर मुझे सही याद है, तो अगर आपने छवि को बीएमपी के रूप में सहेजा है तो यह काम करेगा क्योंकि उस छवि प्रारूप को स्ट्रीम की तलाश किए बिना लिखा जा सकता है।

+0

मैंने वास्तव में कोशिश की लेकिन परिणाम एक ही हो गया। – Serguei

0

ठीक है, मैंने स्ट्रीम के लिए एक रैपर का उपयोग किया है (स्ट्रीम को लागू करता है और एक अंतर्निहित धारा में कॉल पास करता है) यह निर्धारित करने के लिए कि Image.Save() कॉल की स्थिति के बिना स्थिति और लंबाई गुणों को कॉल करता है जो झूठी रिटर्न देता है। यह स्थिति को 0

पर सेट करने का प्रयास करता है, इसलिए ऐसा लगता है कि एक मध्यवर्ती बफर आवश्यक है।

3

Image.Save (मेमोरीस्ट्रीम स्ट्रीम) को मेमोरीस्ट्रीम ऑब्जेक्ट की आवश्यकता होती है जिसे खोजा जा सकता है। संदर्भ। Reesponse.OutputStream केवल अग्रेषित है और मांग का समर्थन नहीं करता है, इसलिए आपको एक मध्यवर्ती धारा की आवश्यकता है। हालांकि, आपको बाइट सरणी बफर की आवश्यकता नहीं है। आप context.Response.OutputStream में अस्थायी स्मृति धारा से सीधे लिख सकते हैं:

/// <summary> 
/// Sends a given image to the client browser as a PNG encoded image. 
/// </summary> 
/// <param name="image">The image object to send.</param> 
private void SendImage(Image image) 
{ 
    // Get the PNG image codec 
    ImageCodecInfo codec = GetCodec("image/png"); 

    // Configure to encode at high quality 
    using (EncoderParameters ep = new EncoderParameters()) 
    { 
     ep.Param[0] = new EncoderParameter(Encoder.Quality, 100L); 

     // Encode the image 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      image.Save(ms, codec, ep); 

      // Send the encoded image to the browser 
      HttpContext.Current.Response.Clear(); 
      HttpContext.Current.Response.ContentType = "image/png"; 
      ms.WriteTo(HttpContext.Current.Response.OutputStream); 
     } 
    } 
} 

एक पूरी तरह कार्यात्मक कोड नमूना यहाँ उपलब्ध है:

Auto-Generate Anti-Aliased Text Images with ASP.NET

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