¿Existe una forma recomendada de devolver una imagen utilizando ASP.NET Web API?

86

¿Cuál es la mejor manera de devolver una imagen con 2 parámetros (xey para cambiar el tamaño)?

Por ejemplo

~/api/image12345/200/200

Devolverá un 200 por 200 jpg / png / o gif

¿Debo devolver un System.Drawing.Imageobjeto o definir manualmente el HTTPReponseMessage.Content?

Max Alexander
fuente
Mira mi respuesta aquí: stackoverflow.com/a/20888749/64334
Ronnie Overby

Respuestas:

147

No debe devolver un System.Drawing.Image, a menos que también agregue un formateador que sepa cómo convertir eso en los bytes apropiados, no se serialice como los bytes de imagen como es de esperar.

Una posible solución es devolver un HttpResponseMessagecon la imagen almacenada en su contenido (como se muestra a continuación). Recuerde que si desea la URL que mostró en la pregunta, necesitará una ruta que asigne los parámetros {imageName}, {width} y {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;
    }
}

Pero nuevamente, si está haciendo esto en muchos lugares, ir por la ruta del formateador puede ser la forma "recomendada". Como casi todo en programación, la respuesta dependerá de tu escenario.

carlosfigueira
fuente
¿La imagen también debería estar en uso?
dibs487
¿Dónde está el GetImagemétodo?
Yoda
1
@Yoda es el método en su implementación que devolvería la imagen que debe transferirse al cliente.
carlosfigueira
Si está devolviendo un archivo desde el disco duro, creo que sería un mejor rendimiento usar un FileStream, como este (consulte la respuesta aceptada en esta pregunta): stackoverflow.com/questions/11125535/…
John Gilmer
19

Las imágenes son pesadas. ASP.NET WebForms, HttpHandlers, MVC y Web API hacen un trabajo absolutamente terrible al servir archivos estáticos. IIS hace un trabajo extremadamente bueno en eso, a menudo de 20 a 100 veces más eficiente.

Si desea obtener un buen rendimiento, reescriba la URL a más tardar durante PostAuthorizeRequest, para que IIS pueda recoger y entregar el archivo. Sí, esto significa manejo de eventos a nivel de HttpModule.

[Descargo de responsabilidad: soy el autor del siguiente artículo y proyecto de código abierto]

Si está haciendo algo dinámico con imágenes, consulte este artículo sobre las dificultades que debe evitar el procesamiento de imágenes y considere echar un vistazo a ImageResizer . Tiene un excelente almacenamiento en caché de disco (que utiliza el manejo de archivos estáticos IIS) y es fácil de conectar a la generación de imágenes de cualquier tipo. También tiene enlaces opcionales para AForge, FreeImage y WIC, si necesita avanzar.

Río lilith
fuente
2
He estado usando ImageResizer en mi proyecto y estoy muy contento con cómo funciona, además de mí. La única queja es que parte de la documentación necesita actualizarse.
Jon L