Hallo,
ich habe folgendes Problem.
Ich generiere on-the-fly ein PNG-Image in ASP.NET.
Mein Problem ist folgendes: Wenn ich den Code lokal (also aus VS 2010) heraus teste, bekomme ich einen SaveFile-Dialog, in dem ich das Bild abspeichern kann.
Lade ich das ganze auf meinen Webserver hoch, klappt das einwandfrei.
Nur leider kann ich nicht dauerhaft meinen Code ständig auf meinen Webserver hochladen.
Wieso habe ich beim lokalen Test dieses Problem?
Code:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ImageAttributes ia = new ImageAttributes();
ColorMatrix cm = new ColorMatrix();
Random r = new Random();
cm.Matrix00 = 1.0f;
cm.Matrix11 = 0.6f;
cm.Matrix22 = 0.0f;
ia.SetColorMatrix(cm);
string strBasePath = Server.MapPath(".");
Bitmap image = new Bitmap(strBasePath+ "/Vogel2.png");
Bitmap newImage = new Bitmap(image.Width, image.Height);
Graphics g = Graphics.FromImage(newImage);
g.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, ia);
MemoryStream io = new MemoryStream();
newImage.Save(io, ImageFormat.Png);
Response.ClearContent();
Response.ContentType = "image/png";
Response.BinaryWrite(io.ToArray());
Response.End();
}
}
Hallo,
nimm zur der Erstellung des Bildes statt der Page lieber einen HttpHandler (generischer Handler, .ashx-Datei).
Mehr dazu in diesem Artikel von Peter Bucher.
Den Umweg über den MemoryStream kannst Du dir sparen das Bild und direkt in den OutputStream der Response speichern.
Warum Du lokal einen Dialog dafür bekommst, ist wohl eher eine Einstellung des Browsers (Zoneneinstellung/Komatibilitätsmodus??)
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Den Umweg über den MemoryStream kannst Du dir sparen das Bild und direkt in den OutputStream der Response speichern.
Nicht, wenn es ein PNG sein soll. Da braucht man zum Speichern einen seekable Stream (was der OutputStream der Response ja nicht ist).
Gruß,
dN!3L
Hallo zusammen
Warum Du lokal einen Dialog dafür bekommst, ist wohl eher eine Einstellung des Browsers (Zoneneinstellung/Komatibilitätsmodus??)
Ja genau.
Wenn du - DomiOh - keine weiteren Angaben über den Content-Disposition Header machst, greift die Standard-Einstellung des Browsers.
Also am besten den Header mit einer expliziten Angabe zum Speichern oder Anzeigen mitgeben.
So müsste es in den meisten Fällen beim Client auch passen. Ausser die Clients ignorieren deinen Header oder setzen die Priorität des Headers niedriger als eigene Einstellungen.
Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011
Auf welchen Wert muss der Content-Disposition Header denn gestellt werden?
Ich habe ihn auf "inline" gestellt. Dennoch erscheint ein SaveAs-Dialog.
Salute DomiOh
Inline passt. Dann kontrolliere mal deine Browsereinstellungen, leere den Cache oder probiere es testweise an einem anderen Computer / Browser aus.
Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011
Hallo dN!3L,
Nicht, wenn es ein PNG sein soll. Da braucht man zum Speichern einen seekable Stream (was der OutputStream der Response ja nicht ist).
Nein sorry. Hab's gerade extra nochmal ausprobiert, funktioniert wunderbar:
public void ProcessRequest (HttpContext context) {
using(Image img = new Bitmap(100, 100)){
Graphics gfx = Graphics.FromImage(img);
gfx.FillEllipse(Brushes.Blue, new Rectangle(0,0,100,100));
img.Save(context.Response.OutputStream, ImageFormat.Png);
}
}
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Nein sorry. Hab's gerade extra nochmal ausprobiert, funktioniert wunderbar
Hm... Also ich habe es ja selbst schon gemacht - bei PNG konnte ich nicht direkt in den OutputStream schreiben. Kann natürlich dran liegen, dass es ASP.NET MVC war. Ich kann dir aber noch eine Quelle nennen:
Zitat von: Scott Hanselman - The Weekly Source Code 50 - A little on "A generic error occurred in GDI+" and trouble generating images on with ASP.NET
The Trick for making PNGs: Without the extra intermediate MemoryStream to save to, you won't be able to make PNGs. You can't image.Save() a PNG directly to Response.OutputStream.
Besten Gruß,
dN!3L
Hallo dN!3L,
ich vermute das bezieht sich nur auf Page-Objekte und nicht auf generische HTTP-Handler. Es gibt da starke Unterschiede, z.B. darf man ja bei einer Page auch überhaupt nicht mehr in die Response schreiben, wenn das Rendering gelaufen ist. Beim HttpHandler existiert eine solche Einschränkung nicht.
Werde aber heute Abend mal anhand Deiner Quelle etwas recherchieren, und es selbst mal in einer Page probieren (was man ja nicht sollte).
Gruß, MarsStein
EDIT: das Geheimnis ist wohl eher, dass es mit dem ASP.NET-Developmentserver von VS funktioniert, aber nicht im IIS (?!)
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca