Serialização de imagens/Images Serialization

Português   English

Existem algumas situações em pode ser necessário inserir uma imagem no seu documento ou página como um código de imagem de forma serializada, sem depender de fontes externas como sites ou do disco rígido.

Alguns exemplos disso estão em aplicações desconectadas onde você possa precisar exibir uma imagem ou um documento html stand alone, como uma documentação ou manual.

Usando o C# e as bibliotecas padrão como System.IO, System.Drawing e System.Drawing.Imaging a tarefa de serialização de imagens em html fica bastante simples requerendo pouco código.

Neste post gostaria de compartilhar um exemplo de como isso é feito apresentando um pequeno programa. Seu propósito é receber um caminho de uma imagem gravada no disco local e retornar uma string com a tag correspondente à imagem serializada.

O projeto criado com o Visual Studio 2017 está disponível no Git Hub para Download. https://github.com/VladimirRech/img2html

Tomando por exemplo a imagem exibida abaixo:

Para gerar o código html com esta aplicação basta enviar o comando:
> img2html.demo d:DocumentosartigosBlogslowers-1375316-639x426.jpg

O código gerado é algo parecido com:

<img src="data:image/.jpg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4S4cRXhpZgAATU0AKgAAAAg
 ACQEPAAIAAAAGAAAAegEQAAIAAAAXAAAAgAESAAMAAAABAAEAAAEaAAUAAAABAAAAmAEbAAUAAAABAAAAoAE
 oAAMAAAABAAIAAAEyAAIAAAAUAAAAqAITAAMAAAABAAIAAIdpAAQAAAABAAAAvAAAFrxDYW5vbgBDYW5vbiB
 ...." />>

No projeto, a classe imgconv.cs é responsável por executar a serialização. A sequência de passos da operação está descrita a seguir.

Inicialmente deve ser passado para o construtor o caminho completo da imagem no disco local (ou caminho da rede). Neste passo são inicializadas as propriedades que darão suporte.

public class imgconv { public string FileFullPath { get; set; } private Dictionary<string, ImageFormat> SupportedImg; private string extension; public imgconv(string fileFullPath) { FileFullPath = fileFullPath; extension = Path.GetExtension(fileFullPath).ToLower(); SupportedImg = new Dictionary<string, ImageFormat> { { ".bmp", ImageFormat.Bmp }, { ".png", ImageFormat.Png }, { ".gif", ImageFormat.Gif }, { ".jpg", ImageFormat.Jpeg } }; } ...

A função da propriedade SupportedImg é manter uma lista de quais extensões e formatos de imagem são compatíveis para executar a serialização. Estes dados são usados durante a execução e também para enviar ao método o formato que será usado.

Para realizar a serialização foi criado o método público GetHtml que precisa receber um array de bytes correspondente a imagem enviada. Esta tarefa é executada por outro método, img2ByteArray.

Se houver dados neste array o método continua transformando os dados contidos neste em uma tag html <img>.

public string GetHtml() { byte[] imgBytes = img2ByteArray(); while (imgBytes != null && imgBytes.Length > 0) { return string.Format( "<img src=\"data:image/{0};base64,{1}\" />", extension, Convert.ToBase64String(imgBytes)); } return null; }

O ponto mais importante da funcionalidade de serialização é o método img2ByteArray que usa a classe MemoryStream para carregar os dados da imagem. Antes desta operação é feita uma verificação se a extensão do arquivo que foi carregada no construtor da classe é suportada.

Se for compatível, a imagem é convertida para o array conforme o formato encontrado e retornada para finalizar a operação.

byte[] img2ByteArray() { using (MemoryStream memoryStream = new MemoryStream()) { while (!SupportedImg.ContainsKey(extension)) return null; using (var img = Image.FromFile(FileFullPath)) img.Save(memoryStream, SupportedImg[extension]); return memoryStream.ToArray(); } }

Considerações

Este código do jeito que está não considera se o conteúdo do arquivo corresponde exatamente à extensão informada. Se for necessário dar mais segurança será necessário fazer esta verificação.

A serialização de imagens só é vantajosa em casos bem específicos como os citados no início e se a imagem for pequena, digamos menor do que 300KB, algo bastante específico. Neste ponto, uma melhoria que pode ser implementada é a verificação do tamanho máximo.

Espero ter contribuído de alguma forma e até a próxima!