Existe uma maneira recomendada de retornar uma imagem usando ASP.NET Web API

86

Qual é a melhor maneira de retornar uma imagem com 2 parâmetros (xey para redimensionar).

Por exemplo

~/api/image12345/200/200

Retornará 200 por 200 jpg / png / ou gif

Devo retornar um System.Drawing.Imageobjeto ou definir manualmente o HTTPReponseMessage.Content?

Max Alexander
fonte
Confira minha resposta aqui: stackoverflow.com/a/20888749/64334
Ronnie Overby

Respostas:

147

Você não deve retornar um System.Drawing.Image, a menos que também adicione um formatador que saiba como convertê-lo nos bytes apropriados não se serialize como os bytes da imagem como você esperaria.

Uma possível solução é retornar um HttpResponseMessagecom a imagem armazenada em seu conteúdo (conforme mostrado abaixo). Lembre-se de que, se você deseja o URL mostrado na pergunta, precisa de uma rota que mapeie os parâmetros {imageName}, {width} e {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;
    }
}

Mas, novamente, se você estiver fazendo isso em muitos lugares, seguir o caminho do formatador pode ser o caminho "recomendado". Como quase tudo na programação, a resposta dependerá do seu cenário.

carlosfigueira
fonte
A imagem também deve ser usada?
dibs487
Onde está o GetImagemétodo?
Yoda
1
@Yoda é o método em sua implementação que retornaria a imagem que precisa ser transferida de volta para o cliente.
carlosfigueira
Se você estiver devolvendo um arquivo do disco rígido, acho que seria um desempenho melhor usar um FileStream, como este (veja a resposta aceita nesta pergunta): stackoverflow.com/questions/11125535/…
John Gilmer
19

As imagens são pesadas. ASP.NET WebForms, HttpHandlers, MVC e Web API fazem um trabalho absolutamente terrível de servir arquivos estáticos. O IIS faz um trabalho extremamente bom nisso - geralmente de 20 a 100 vezes mais eficiente.

Se você deseja obter um bom desempenho, faça a regravação da URL o mais tardar durante PostAuthorizeRequest, para que o IIS possa selecionar e servir o arquivo. Sim, isso significa manipulação de eventos no nível do HttpModule.

[Aviso: sou o autor do seguinte artigo e projeto de código aberto]

Se você estiver fazendo algo dinâmico com imagens, verifique este artigo sobre as armadilhas do processamento de imagens a serem evitadas e considere dar uma olhada em ImageResizer . Possui excelente cache de disco (que usa manipulação de arquivos estáticos IIS) e é fácil de conectar para geração de imagens de qualquer tipo. Ele tem ligações opcionais para AForge, FreeImage e WIC também, se você precisar avançar.

Lilith River
fonte
2
Tenho usado o ImageResizer em meu projeto e estou muito feliz com a forma como ele funciona - além de mim. Apenas reclamação é que parte da documentação precisa de atualização.
Jon L