C# - Convertendo Imagem para Array de bytes e vice-versa


Hoje veremos como converter uma imagem para um array de bytes, salvar em um arquivo e fazer o processo inverso.

Em muitas situações, você pode ser forçado a ter que converter uma imagem em um array de bytes.

Esse é um recurso útil pois um array de bytes pode ser comparado, compactado e armazenado ou convertido em outros tipos de dados.

Podemos fazer essa conversão de várias maneiras, mas as duas maneiras mais eficientes são:

  1. Via MemoryStream
using (MemoryStream mStream = new MemoryStream())
{
    img.Save(mStream, imagem.RawFormat);
    return mStream.ToArray();
}

O objeto Image possui uma função Save, que permite aos desenvolvedores salvar uma imagem em um arquivo em qualquer formato de imagem suportado pelo .NET Framework.

Neste exemplo, a função Save é aplicada ao objeto MemoryStream, enquanto especifica um formato de imagem. Como o objeto está na memória, ele pode ser facilmente convertido em um array de bytes com a função ToArray do objeto MemoryStream.

A propriedade RawFormat do parâmetro Image, retorna o formato do arquivo da imagem.

Tanto o objeto MemoryStream como o objeto Image possuem um método dispose, e, é sempre recomendável que você descarte os objetos usados em um bloco using.

  1. Via ImageConverter
ImageConverter imagem = new ImageConverter();
return (byte[])imagem.ConvertTo(inImagem, typeof(byte[]));

A classe ImageConverter é uma classe que pode ser usada para converter objetos Image de um tipo de dados para outro. O processo inverso é feito de maneira bem simples pelo código a seguir:

using (MemoryStream mStream = new MemoryStream(byteArrayIn))
{
    return Image.FromStream(mStream);
}

Vejamos a seguir um exemplo prático de cada uma dessas opções reunidos em um projeto Windows Forms.

recursos usados:

Criando o projeto Windows Forms

Vamos então criar um projeto do tipo Windows Forms App(.NET Framework) no VS 2019 Community no menu File -> New Project, com o nome WF_ImagemBytes;

Nota:  Estou usando o NET Framework 4.7.2

No formulário Form1.cs inclua os seguintes controles:

Defina o leiaute do formulário conforme a imagem a seguir:

Os namespaces usados no projeto são:

using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

Variáveis globais usadas no formulário:

OpenFileDialog ofd1 = new OpenFileDialog();
string local = @"c:\dados\imgs";

1- Convertendo de Imagem para um array de bytes e salvando como um arquivo

No botão Carregar Imagem temos o código que vai permitir selecionar uma imagem e exibir no PictureBox:

      private void btnCarregaImagem_Click(object sender, EventArgs e)
    {
            ofd1.Multiselect = true;
            ofd1.Title = "Selecionar Imagems";
            ofd1.InitialDirectory = @"C:\Users\users\Pictures";
            //filtra para exibir somente arquivos de imagens
            ofd1.Filter = "Images (*.BMP;*.JPG;*.GIF,*.PNG,*.TIFF)|*.BMP;*.JPG;*.GIF;*.PNG;*.TIFF|" + "All files (*.*)|*.*";
            ofd1.CheckFileExists = true;
            ofd1.CheckPathExists = true;
            ofd1.FilterIndex = 2;
            ofd1.RestoreDirectory = true;
            ofd1.ReadOnlyChecked = true;
            ofd1.ShowReadOnly = true;
            DialogResult dr = ofd1.ShowDialog();
            if (dr == System.Windows.Forms.DialogResult.OK)
            {
                picImagem.SizeMode= PictureBoxSizeMode.StretchImage;
                picImagem.Image = Image.FromFile(ofd1.FileName);
                btnConverteImagem.Enabled = true;
            }
        }

No botão - Converter Imagem - temos o código que converte a imagem para um array de bytes e salva a imagem na pasta c:\dados\imgs" como um arquivo

       private void btnConverteImagem_Click(object sender, EventArgs e)
        {
            try
            {
                //imagem para byteArray
                Image minhaImagem = Image.FromFile(ofd1.FileName);
                byte[] meuArrayBytes = ConverteImagemParaByteArray(minhaImagem);
                SalvaArrayBytesEmArquivo(meuArrayBytes);
                ExibirArquivos();
                picImagem.Image = null;
            }
            catch (Exception)
            {
                throw;
            }
        }

Aqui temos os métodos ConverteImagemParaByteArray() que vai converter a imagem, o método  SalvaArrayBytesEmArquivo(meuArrayBytes) que salva o array de bytes para um arquivo, e o ExibirArquivos() que exibe os arquivos gerados na pasta:

1- ConverteImagemParaByteArray()

         public byte[] ConverteImagemParaByteArray(Image img)
        {
            try
            {
                using (MemoryStream mStream = new MemoryStream())
                {
                    img.Save(mStream, img.RawFormat);
                    return mStream.ToArray();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

2- SalvaArrayBytesEmArquivo()

        public void SalvaArrayBytesEmArquivo(byte[] array)
        {
            try
            {
                using (MemoryStream ms = new MemoryStream(array))
                {
                    string nome = Path.GetRandomFileName();
                    string arquivo = Path.Combine(local, nome);
                    //escreve para arquivo
                    FileStream file = new FileStream(arquivo, FileMode.Create, FileAccess.Write);
                    ms.WriteTo(file);
                    file.Close();
                    ms.Close();
                    MessageBox.Show("Arquivo : >> " + arquivo + "  gerado com sucesso");
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

3- ExibirArquivos()

public void ExibirArquivos()
{
    string[] txtfiles = Directory.GetFiles(local, "*.*");
    lbArquivos.Items.AddRange(txtfiles);
}

Exibe os arquivos da pasta c:\dados\imgs no ListBox.

2- Convertendo de arquivo para bytes e para Imagem

No botão - Gerar Imagem - temos o código que vai converter um arquivo selecionado no ListBox para uma imagem e exibir no Picturebox:

       private void btnGerarImagem_Click(object sender, EventArgs e)
        {
            try
            {
                string arquivo = lbArquivos.Text;
                byte[] arquivoBytes = ConverteArquivoBytes(arquivo);
                Image img1 = ConverteByteParaImagem(arquivoBytes);
                picImagem.SizeMode = PictureBoxSizeMode.StretchImage;
                picImagem.Image = img1;
            }
            catch (Exception)
            {
                throw;
            }
        }

 

Neste código temos os métodos ConvertetArquivoBytes() que vai converter o arquivo selecionado para um array de bytes, e o método ConverteByteParaImagem() que vai converter o array de bytes para Imagem e exibir no Picturebox:

1- ConverteArquivoBytes()

      private byte[] ConverteArquivoBytes(string arquivo)
        {
            try
            {
                using (FileStream fs = new FileStream(arquivo, FileMode.Open, FileAccess.Read))
                {
                    // cria um array de byte do arquivo
                    byte[] bytes = System.IO.File.ReadAllBytes(arquivo);
                    //le o bloco de bytes do stream
                    fs.Read(bytes, 0, System.Convert.ToInt32(fs.Length));
                    return bytes;
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

2- ConverteByteParaImagem()

        private Image ConverteByteParaImagem(byte[] arquivo)
        {
            try
            {
                using (MemoryStream mStream = new MemoryStream(arquivo))
                {
                    return Image.FromStream(mStream);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

Executando projeto teremos o resultado abaixo:

Pegue o projeto completo aqui :  WF_ImagemBytes.zip

"Portanto, agora nenhuma condenação há para os que estão em Cristo Jesus, que não andam segundo a carne, mas segundo o Espírito."
Romanos 8:1

Referências:


José Carlos Macoratti