Gibt es eine empfohlene Möglichkeit, ein Bild mithilfe der ASP.NET-Web-API zurückzugeben?

86

Was ist der beste Weg, um ein Bild mit 2 Parametern zurückzugeben (x und y für die Größenänderung).

Beispielsweise

~/api/image12345/200/200

Gibt ein 200 x 200 jpg / png / oder gif zurück

Soll ich ein System.Drawing.ImageObjekt zurückgeben oder das manuell definieren HTTPReponseMessage.Content?

Max Alexander
quelle
Schauen Sie sich meine Antwort hier an: stackoverflow.com/a/20888749/64334
Ronnie Overby

Antworten:

146

Sie sollten a nicht zurückgeben System.Drawing.Image, es sei denn, Sie fügen auch einen Formatierer hinzu, der weiß, wie man das in die entsprechenden Bytes konvertiert, und serialisiert sich nicht wie erwartet als Bildbytes.

Eine mögliche Lösung besteht darin, ein HttpResponseMessageBild mit dem in seinem Inhalt gespeicherten Bild zurückzugeben (siehe unten). Denken Sie daran, dass Sie eine Route benötigen, die die Parameter {imageName}, {width} und {height} zuordnet, wenn Sie die in der Frage angezeigte URL verwenden möchten.

public HttpResponseMessage Get(string imageName, int width, int height)
{
    Image img = GetImage(imageName, width, height);
    using(MemoryStream ms = new MemoryStream())
    {
        img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);

        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        result.Content = new ByteArrayContent(ms.ToArray());
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");

        return result;
    }
}

Wenn Sie dies jedoch an vielen Stellen tun, ist die Formatierungsroute möglicherweise die "empfohlene" Methode. Wie fast alles in der Programmierung hängt die Antwort von Ihrem Szenario ab.

carlosfigueira
quelle
Sollte das Bild auch verwendet werden?
Dibs487
Wo ist die GetImageMethode?
Yoda
1
@Yoda Es ist die Methode in Ihrer Implementierung, die das Image zurückgibt, das zurück an den Client übertragen werden muss.
Carlosfigueira
Wenn Sie eine Datei von der Festplatte zurückgeben, ist es meiner Meinung nach besser, einen FileStream wie diesen zu verwenden (siehe akzeptierte Antwort in dieser Frage): stackoverflow.com/questions/11125535/…
John Gilmer
19

Bilder sind schwer. ASP.NET WebForms, HttpHandlers, MVC und Web API leisten alle einen absolut schrecklichen Job beim Bereitstellen statischer Dateien. IIS macht das sehr gut - oft 20-100x effizienter.

Wenn Sie eine gute Leistung erzielen möchten, schreiben Sie die URL spätestens während PostAuthorizeRequest neu, damit IIS die Datei abrufen und bereitstellen kann. Ja, dies bedeutet Ereignisbehandlung auf HttpModule-Ebene.

[Haftungsausschluss: Ich bin der Autor des folgenden Artikels und Open-Source-Projekts]

Wenn Sie mit Bildern etwas Dynamisches tun, lesen Sie diesen Artikel über Fallstricke bei der Bildverarbeitung , um dies zu vermeiden , und schauen Sie sich ImageResizer an . Es verfügt über ein hervorragendes Festplatten-Caching (das die statische Behandlung von IIS-Dateien verwendet) und lässt sich leicht mit der Bilderzeugung jeglicher Art verbinden. Es hat optionale Bindungen für AForge, FreeImage und WIC, falls Sie fortgeschritten sein müssen.

Lilith River
quelle
2
Ich habe ImageResizer in meinem Projekt verwendet und bin sehr zufrieden mit der Funktionsweise - plus von mir. Einziger Kritikpunkt ist, dass ein Teil der Dokumentation aktualisiert werden muss.
Jon L