Results for tag "gdi-2"

ASP.net – Bitmap (.bmp) in den OutputStream rendern – Render Bitmap into Outputstream

Hallo Leute,

mal wieder was Spannendes. Beim Versuch eine BMP-Grafik direkt in den Outputstream einer ASP.net Webpage zu rendern, tritt eine Exception auf (System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+.).

Spannende Geschichte, denn der gleiche Quellcode funktioniert mit JPG-Grafiken:

[sourcecode language=“csharp“]
Response.Clear();
Response.ContentType = "image/jpeg"; // "image/bmp" does not work!

Image orgChartImage = (System.Drawing.Image)Cache[imageName];
orgChartImage.Save(this.Response.OutputStream);
orgChartImage.Dispose();
[/sourcecode]

Bei meiner Recherche bin ich über den Blog von Rick Stahl gestolpert, der das gleiche Problem mit PNG-Grafiken beschreibt, siehe:

Rick Stahl’s Blog

In den Kommentaren schreibt u.a. Russ Garner, dass das daran liegen kann, dass der Encoder von PNG-Grafiken einen bi-directional Stream benötigt und postet gleichzeitig auch die Lösung:

Png’s are a special case. Their encoder requires a bi-directional stream. The solution is to stream to a memory stream first and write the contents of that memory stream to OutputStream afterwards.

When you get to caching (which I’ve just implemented) you’ll be writing to a memory stream anyway just to cache the output, so this isn’t a big deal.

As far as the GIF end of things goes, the default palletization of the built in GIF encoder leaves something to be desired. I’ve built in support for an Octree quantizer to deal with this.

Seriously – it’s a lot of work. It’s probably easier if I just send you some code 😉

Umgemünzt auf unser Beispiel bedeutet dies folgenden Sourcecode:

[sourcecode language=“csharp“]
string imageName = Request.QueryString["ID"];
Bitmap bm2 = (System.Drawing.Bitmap)Cache[imageName];
Bitmap bm3 = new Bitmap(bm2);

MemoryStream ms = new MemoryStream();

Response.ContentType = "image/bmp";
bm3.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
ms.WriteTo(Response.OutputStream);

bm2.Dispose();
bm3.Dispose();
Response.End();
[/sourcecode]

Eine schlüssigere Fehlermeldung wäre mal was gewesen …
Ich hoffe, ich rette euch mit diesen Codesnippets ein paar Stunden eurer wertvollen Zeit!

Cheers,
Chris