Czy istnieje zalecany sposób zwracania obrazu przy użyciu interfejsu API sieci Web ASP.NET


Odpowiedzi:


147

Nie powinieneś zwracać a System.Drawing.Image, chyba że dodasz również program formatujący, który wie, jak przekonwertować to na odpowiednie bajty, nie serializuje się jako bajty obrazu, jak można się spodziewać.

Jednym z możliwych rozwiązań jest zwrócenie pliku HttpResponseMessagez obrazem przechowywanym w jego treści (jak pokazano poniżej). Pamiętaj, że jeśli potrzebujesz adresu URL, który pokazałeś w pytaniu, potrzebujesz trasy, która odwzorowuje parametry {imageName}, {width} i {height}.

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;
    }
}

Ale znowu, jeśli robisz to w wielu miejscach, skorzystanie z trasy formatera może być sposobem „zalecanym”. Jak prawie wszystko w programowaniu, odpowiedź będzie zależeć od twojego scenariusza.


Czy obraz powinien być również używany?
dibs487

Gdzie jest GetImagemetoda?
Yoda

1
@Yoda to metoda w Twojej implementacji, która zwróci obraz, który należy przesłać z powrotem do klienta.
carlosfigueira

Jeśli zwracasz plik z dysku twardego, myślę, że lepszą wydajność byłoby użycie FileStream, w ten sposób (patrz zaakceptowana odpowiedź w tym pytaniu): stackoverflow.com/questions/11125535/ ...
John Gilmer

19

Obrazy są ciężkie. ASP.NET WebForms, HttpHandlers, MVC i Web API wykonują absolutnie straszną robotę obsługującą pliki statyczne. Usługi IIS wykonują bardzo dobrą robotę - często 20-100 razy wydajniej.

Jeśli chcesz uzyskać dobrą wydajność, przeprowadź ponowne zapisywanie adresu URL najpóźniej podczas PostAuthorizeRequest, aby usługi IIS mogły odebrać i udostępnić plik. Tak, oznacza to obsługę zdarzeń na poziomie HttpModule.

[Uwaga: jestem autorem następującego artykułu i projektu open source]

Jeśli robisz coś dynamicznego z obrazami, zapoznaj się z tym artykułem na temat pułapek przetwarzania obrazu, których należy unikać , i rozważ przyjrzenie się ImageResizer . Ma doskonałe buforowanie dysku (które wykorzystuje statyczną obsługę plików IIS) i jest łatwe do podłączenia do dowolnego rodzaju generowania obrazu. Ma również opcjonalne powiązania dla AForge, FreeImage i WIC, jeśli chcesz przejść zaawansowany.


2
Używam ImageResizera w moim projekcie i jestem bardzo zadowolony z jego działania - plus ode mnie. Jedynym problemem jest to, że część dokumentacji wymaga aktualizacji.
Jon L,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.