Jump to content
Fórum Script Brasil
  • 0

Não Consigo Converter Binarios (byte[]) para uma Imagem (Image)


rodrigo_arf

Question

Bom Dia Pessoal,

Bom é o seguinte a 3 dias estou desenvolvendo um projeto em trabalho relacionado a webcans, em Windows Forms, Framework 3.5, Visual Studio 2010.

já a base de dados é Oracle, com PL/Sql.

O que acontece é o seguinte, eu tiro uma foto do visitante e Converto essa imagem em Byte[] e salvo no Oracle em uma tabela que tem um campo já configurado como BLOB para armazenar grandes quantidades de dados, bom isso esta OK pois estou salvando corretamente a imagem imagem e pela ferramenta PL/Sql eu ate consigo ver a Fotinho do miliante la.

O Problema é que quando eu dou um Select nesta tabela e pego as informaçoes para exibir em um Form esta dando problema para Converter os Bynarios (byte[]) em Imagem do tipo (Image) para exibir em uma PictureBox, a verdade é que procurei em todos os Foruns e teste tambem varios exemplos e não cheguei a uma resposta convincente nem a solução deste problema.

o erro é "Parametro Invalido";

meu codigo é esse:

public static Image ConverteByteArrayEmImagem(byte[] _BytesDaImagem) 
        {
            Image _ImagemDoArray;
            using (MemoryStream _Memoria = new MemoryStream(_BytesDaImagem, 0, _BytesDaImagem.Length))
            {                
                _Memoria.Write(_BytesDaImagem, 0, _BytesDaImagem.Length);
                _ImagemDoArray = Image.FromStream(_Memoria, true,true);
            }
            return (_ImagemDoArray);
        }
a linha que da o erro é essa :
_Memoria.Write(_BytesDaImagem, 0, _BytesDaImagem.Length);
Depois disso mudei algumas coisas mas da o mesmo erro, estou usando 'ImageConverter' :
ImageConverter ConversorDeImagem = new ImageConverter();
Image ImagemGerada = (Image)ConversorDeImagem.ConvertFrom(objVisitante.BinarioDoArquivoDeImagem);

Não sei onde pode ser, a unica certesaque tenho é que a os Bynarios da Imagem esta la certinho na tabela pois quando exibo pelo PL/Sql ele mostra a imagem para mim direto dos Bytes.

Minhas suspeitas era de não tivem todos os Bytes na tabela por algum motivo mas não é.

Outra Suspeita é na hora de dar o Select na tabela ele por algum motivo retornar itens do byte[] errados ou faltando alguma coisa em fim.

fora isso não sei mais o que pode ser.

Se algum já passou por isso ou quiser dar uma dica do que fazer estou a ouvidos....

: )...

meu MSN é rodrigo_arf@hotmail.com

Sou Desenvolvedor de Sistemas .NET com 4 anos de experiencia, quem quiser me adicionar.

Link to comment
Share on other sites

10 answers to this question

Recommended Posts

  • 0

Rodrigo, tente desta forma:

public static Image ConverteByteArrayEmImagem(byte[] _BytesDaImagem)
{
    Image _ImagemDoArray;
    MemoryStream _Memoria = new MemoryStream(_BytesDaImagem);

    _ImagemDoArray.FromStream(_Memoria);

    return (_ImagemDoArray);
}

Não há necessidade de escrever o memorystream novamente, sendo que este já recebeu o array de bites vindo do banco.

Link to comment
Share on other sites

  • 0
Rodrigo, tente desta forma:

public static Image ConverteByteArrayEmImagem(byte[] _BytesDaImagem)
{
    Image _ImagemDoArray;
    MemoryStream _Memoria = new MemoryStream(_BytesDaImagem);

    _ImagemDoArray.FromStream(_Memoria);

    return (_ImagemDoArray);
}

Não há necessidade de escrever o memorystream novamente, sendo que este já recebeu o array de bites vindo do banco.

Puts cara infelizmente deu, o erro permanece: 'Parâmetro Invalido'...

não sei o que pode ser...

:(...

Link to comment
Share on other sites

  • 0
Seu _BytesDaImagem está retornando normalmente?

Aparentemente sim, rsss, por que quando dou um select na tabela pelo PL/Sql e clico duas vezes na celula da coluna que é o campo BLOB o proprio PL me mostra em uma janela com algumas abas onde posso ver a Imagem, o codigo Binario com Hexa em fim...

Tipo pelo que estou achamando não sei se é o tipo de Hexa se é 64 já esta parte não entendo muito, não sei se pode ser isso.

mas segue algumas funções:

Essa esta correta e em uso:

public static byte[] ConverteImagemEmByteArray(Image _Imagem) 
        {
            Image _ImagemClone = (Image)_Imagem.Clone();
            MemoryStream _Memoria = new MemoryStream();
            _ImagemClone.Save(_Memoria, System.Drawing.Imaging.ImageFormat.Jpeg);

            return (_Memoria.GetBuffer());
        }
Essa é a que contem o erro 'Parametro Invalido'
public static Image ConverteByteArrayEmImagem(byte[] _BytesDaImagem) 
        {
            Image _ImagemDoArray;
            MemoryStream _Memoria = new MemoryStream(_BytesDaImagem);
            _ImagemDoArray = Image.FromStream(_Memoria);

            return (_ImagemDoArray);
        }
O erro que retorna do Visual Studio 2010 é esse abaixo. erro.jpg minha classe tipada é essa abaixo:
public class Visitante : ICloneable
    {
        public String CodigoDoVisitante { get; set; }
        public String NomeDoVisitante { get; set; }
        public String Endereco {get; set;}
        public String Numero { get; set; }
        public String Bairro { get; set; }
        public String Cidade { get; set; }
        public String Estado { get; set; }
        public String Cep { get; set; }
        public String DocumentoRg { get; set; }
        public String DocumentoCpf { get; set; }
        public String Telefone { get; set; }
        public String Celular { get; set; }
        public String DataDeNascimento { get; set; }
        public String NomeDoArquivoDeImagem { get; set; }
        public byte [] BinarioDoArquivoDeImagem { get; set; }
        public String DataDeCadastro { get; set; }
        public object Clone() 
        {
            Visitante objVisitate = new Visitante();            
            objVisitate.CodigoDoVisitante = this.CodigoDoVisitante;
            objVisitate.NomeDoVisitante = this.NomeDoVisitante;
            objVisitate.Endereco = this.Endereco;
            objVisitate.Numero = this.Numero;
            objVisitate.Bairro = this.Bairro;
            objVisitate.Cidade = this.Cidade;
            objVisitate.Estado = this.Estado;
            objVisitate.Cep = this.Cep;
            objVisitate.DocumentoRg = this.DocumentoRg;
            objVisitate.DocumentoCpf = this.DocumentoCpf;
            objVisitate.Telefone = this.Telefone;
            objVisitate.Celular = this.Celular;
            objVisitate.DataDeNascimento = this.DataDeNascimento;
            objVisitate.NomeDoArquivoDeImagem = this.NomeDoArquivoDeImagem;
            objVisitate.BinarioDoArquivoDeImagem = this.BinarioDoArquivoDeImagem;
            objVisitate.DataDeCadastro = this.DataDeCadastro;
            return (objVisitate);
        }

        public override string ToString()
        {
            return (CodigoDoVisitante + " - " + NomeDoVisitante);
        }
    }

já não sei mais o que faço... rsss :) que coisa não...

Mas continuo procurando se alguém tiver sugestoes por favor me mande...

Link to comment
Share on other sites

  • 0

Rodrigo, até onde conheço esse erro é devido a um índice do array estar vazio. Já testou montar um arquivo com esse array?

public void ConverteByteEmArray()
{
     Byte[] _BytesDaImagem = CriaImagem();
     Image _ImagemDoArray;

     try
    {
          using (MemoryStream _Memoria = new MemoryStream(_BytesDaImagem, 0, _BytesDaImagem.Length))
               _Memoria.Write(_BytesDaImagem, 0, _imageArray.Length);
               _ImagemDoArray= Image.FromStream(_Memoria);
          End Using
     }
     catch (Exception ex)
     {
          MessageBox.Show(ex.Exception);
     }
}

public byte[] CriaImagem()
{
    byte[] ArrayImagem;
    Image _Imagem = new Bitmap(1, 1)

    using (MemoryStream _Memoria = New MemoryStream())
    {
        _Imagem.Save(_Memoria , ImageFormat.Jpeg);
        ArrayImagem= _Memoria.ToArray;
    }
    return imageArray;
}

Link to comment
Share on other sites

  • 0
Rodrigo, até onde conheço esse erro é devido a um índice do array estar vazio. Já testou montar um arquivo com esse array?

public void ConverteByteEmArray()
{
     Byte[] _BytesDaImagem = CriaImagem();
     Image _ImagemDoArray;

     try
    {
          using (MemoryStream _Memoria = new MemoryStream(_BytesDaImagem, 0, _BytesDaImagem.Length))
               _Memoria.Write(_BytesDaImagem, 0, _imageArray.Length);
               _ImagemDoArray= Image.FromStream(_Memoria);
          End Using
     }
     catch (Exception ex)
     {
          MessageBox.Show(ex.Exception);
     }
}

public byte[] CriaImagem()
{
    byte[] ArrayImagem;
    Image _Imagem = new Bitmap(1, 1)

    using (MemoryStream _Memoria = New MemoryStream())
    {
        _Imagem.Save(_Memoria , ImageFormat.Jpeg);
        ArrayImagem= _Memoria.ToArray;
    }
    return imageArray;
}
Bom Dia Amigo toca mais uma vez nois aqui de novo, viu seguinte o erro pode estar aqui tambem não sei se voce concorda, na função que dou um Select no banco e pelo os campos que vou usar para exibir no form eu faço deste jeito para pegar as informações no caso a coluna BLOB do Oracle
public List<Visitante> retVisitante(String CodigoDoVisitante, String NomeDoVisitante, String TipoBusca)
        {
            String sqlquery = String.Empty;
            List<Visitante> lstVisitante = new List<Visitante>();

            if ((CodigoDoVisitante == String.Empty) && (NomeDoVisitante == String.Empty) && (TipoBusca == String.Empty))
            {
                sqlquery = "SELECT A.COD_VISIT, A.NM_VISIT, A.ENDERECO, A.NUMERO, A.BAIRRO, A.CIDADE, A.ESTADO, A.CEP, A.DOC_RG, A.DOC_CPF, A.TELEFONE, A.CELULAR, TO_DATE(A.DTHR_NASC) AS DTHR_NASC, A.ARQ_IMG, A.BIN_IMG, A.DTHR_CAD FROM MED.SP_VISITANTE A ORDER BY 2 ASC";
            }
            else if ((CodigoDoVisitante == String.Empty) && (NomeDoVisitante != String.Empty) && (TipoBusca != String.Empty))
            {
                switch (TipoBusca)
                { 
                    case "1" :
                        sqlquery = "SELECT A.COD_VISIT, A.NM_VISIT, A.ENDERECO, A.NUMERO, A.BAIRRO, A.CIDADE, A.ESTADO, A.CEP, A.DOC_RG, A.DOC_CPF, A.TELEFONE, A.CELULAR, TO_DATE(A.DTHR_NASC) AS DTHR_NASC, A.ARQ_IMG, A.BIN_IMG, A.DTHR_CAD FROM MED.SP_VISITANTE A WHERE A.NM_VISIT LIKE '" + NomeDoVisitante + "%' ORDER BY 2 ASC";
                        break;
                    case "2" :
                        sqlquery = "SELECT A.COD_VISIT, A.NM_VISIT, A.ENDERECO, A.NUMERO, A.BAIRRO, A.CIDADE, A.ESTADO, A.CEP, A.DOC_RG, A.DOC_CPF, A.TELEFONE, A.CELULAR, TO_DATE(A.DTHR_NASC) AS DTHR_NASC, A.ARQ_IMG, A.BIN_IMG, A.DTHR_CAD FROM MED.SP_VISITANTE A WHERE A.NM_VISIT LIKE '%" + NomeDoVisitante + "%' ORDER BY 2 ASC";
                        break;
                    case "3":
                        sqlquery = "SELECT A.COD_VISIT, A.NM_VISIT, A.ENDERECO, A.NUMERO, A.BAIRRO, A.CIDADE, A.ESTADO, A.CEP, A.DOC_RG, A.DOC_CPF, A.TELEFONE, A.CELULAR, TO_DATE(A.DTHR_NASC) AS DTHR_NASC, A.ARQ_IMG, A.BIN_IMG, A.DTHR_CAD FROM MED.SP_VISITANTE A WHERE A.NM_VISIT = '" + NomeDoVisitante + "' ORDER BY 2 ASC";
                        break;
                }                
            }
            else if ((CodigoDoVisitante != String.Empty) && (NomeDoVisitante != String.Empty))
            {
                sqlquery = "SELECT A.COD_VISIT, A.NM_VISIT, A.ENDERECO, A.NUMERO, A.BAIRRO, A.CIDADE, A.ESTADO, A.CEP, A.DOC_RG, A.DOC_CPF, A.TELEFONE, A.CELULAR, TO_DATE(A.DTHR_NASC) AS DTHR_NASC, A.ARQ_IMG, A.BIN_IMG, A.DTHR_CAD FROM MED.SP_VISITANTE A WHERE A.COD_VISIT = " + CodigoDoVisitante + " OR A.NM_VISIT LIKE '" + NomeDoVisitante + "' ORDER BY 2 ASC";
            }

            using (ConectaOracle dbConn = new ConectaOracle(sqlquery, Configuracao.Conexao))
            {
                Visitante objVisitante;
                dbConn.Open();
                while (dbConn.LerRegistro())
                {
                    objVisitante = new Visitante();

                    objVisitante.CodigoDoVisitante = dbConn.Ler("COD_VISIT").ToString();
                    objVisitante.NomeDoVisitante = dbConn.Ler("NM_VISIT").ToString();
                    objVisitante.Endereco = dbConn.Ler("ENDERECO").ToString();
                    objVisitante.Numero = dbConn.Ler("NUMERO").ToString();
                    objVisitante.Bairro = dbConn.Ler("BAIRRO").ToString();
                    objVisitante.Cidade = dbConn.Ler("CIDADE").ToString();
                    objVisitante.Estado = dbConn.Ler("ESTADO").ToString();
                    objVisitante.Cep = dbConn.Ler("CEP").ToString();
                    objVisitante.DocumentoRg = dbConn.Ler("DOC_RG").ToString();
                    objVisitante.DocumentoCpf = dbConn.Ler("DOC_CPF").ToString();
                    objVisitante.Telefone = dbConn.Ler("TELEFONE").ToString();
                    objVisitante.Celular = dbConn.Ler("CELULAR").ToString();

                    if (String.IsNullOrEmpty(dbConn.Ler("DTHR_NASC").ToString()))
                    {
                        objVisitante.DataDeNascimento = String.Empty;
                    }
                    else
                    {
                        objVisitante.DataDeNascimento = dbConn.Ler("DTHR_NASC").ToString().Substring(0, 10);
                    }
                    
                    if (dbConn.Ler("BIN_IMG").ToString() != String.Empty)
                    {
                        System.Text.ASCIIEncoding Codificacao = new System.Text.ASCIIEncoding();
                        byte[] BytesDaImagem = Codificacao.GetBytes(dbConn.Ler("BIN_IMG").ToString());
                        objVisitante.BinarioDoArquivoDeImagem = BytesDaImagem;
                    }
                    else
                    {
                        objVisitante.BinarioDoArquivoDeImagem = null;
                    }                    
                    objVisitante.DataDeCadastro = dbConn.Ler("DTHR_CAD").ToString();
                    lstVisitante.Add(objVisitante);
                }
            }
            return (lstVisitante);
        }
Somente explicando rapidamente essa função retorna um List<Visitante> contendo variso objetos para eu exibir no DataGrid do form, essa função da entrada no banco no caso um Select e quando vai pegar o campo que contem Bynarios da Imgem eu faço a seguinte instrução que eu acho que esteja errado né:
if (dbConn.Ler("BIN_IMG").ToString() != String.Empty)
                    {
                        System.Text.ASCIIEncoding Codificacao = new System.Text.ASCIIEncoding();
                        byte[] BytesDaImagem = Codificacao.GetBytes(dbConn.Ler("BIN_IMG").ToString());
                        objVisitante.BinarioDoArquivoDeImagem = BytesDaImagem;
                    }
                    else
                    {
                        objVisitante.BinarioDoArquivoDeImagem = null;
                    }
onde a linha
dbConn.Ler("BIN_IMG").ToString()

é o campo da tabela onde tem o BLOB contendo os bynarios quando pelo ele utilizo o objeto 'System.Text.ASCIIEncoding' com o metodo 'GetBytes' para preencher minha variavel 'BytesDaImagem' não sei se o erro pode estar ai nesta linha, antes disso ate a parte que salva no banco esta tudo OK.

bom vou tentar o que você me disse no poste anterior a essa resposta... pois ainda não tentei... breve posto aqui o ocorrido. :)...

Link to comment
Share on other sites

  • 0

Legal Rodrigo! Eu nunca usei esse tipo de problema, mas você pesquisando ai e eu aqui acho que dará certo. Vi sobre um objeto chamado OracleBinary para receber dados de um campo Blob. Já usou ou ouviu falar?

Ele faz parte do namespace System.Data.OracleClient.OracleBinary. O exemplo que vi era usado em conjunto com um OracleDataReader (reader no exemplo abaixo).

if (dbConn.Ler("BIN_IMG").ToString() != String.Empty)
{
     OracleBinary binario = reader.GetOracleBinary(indiceCampoBLOB);
     byte[] BytesDaImagem = binario.Value;
     objVisitante.BinarioDoArquivoDeImagem = BytesDaImagem;
}
else
{
     objVisitante.BinarioDoArquivoDeImagem = null;
}

Edited by Xistyle
Link to comment
Share on other sites

  • 0
Legal Rodrigo! Eu nunca usei esse tipo de problema, mas você pesquisando ai e eu aqui acho que dará certo. Vi sobre um objeto chamado OracleBinary para receber dados de um campo Blob. Já usou ou ouviu falar?

Ele faz parte do namespace System.Data.OracleClient.OracleBinary. O exemplo que vi era usado em conjunto com um OracleDataReader (reader no exemplo abaixo).

if (dbConn.Ler("BIN_IMG").ToString() != String.Empty)
{
     OracleBinary binario = reader.GetOracleBinary(indiceCampoBLOB);
     byte[] BytesDaImagem = binario.Value;
     objVisitante.BinarioDoArquivoDeImagem = BytesDaImagem;
}
else
{
     objVisitante.BinarioDoArquivoDeImagem = null;
}
Ola 'Xistyle' e para o pessoal do Forum aqui, seguinte: Encontrei o erro no meu codigo, como estou fazendo em tres camadas a minha classe DAL que acessa as informações do banco estava errado a seguinte função
if (dbConn.Ler("BIN_IMG").ToString() != String.Empty)
                    {
                        System.Text.ASCIIEncoding Codificacao = new System.Text.ASCIIEncoding();
                        byte[] BytesDaImagem = Codificacao.GetBytes(dbConn.Ler("BIN_IMG").ToString());
                        objVisitante.BinarioDoArquivoDeImagem = BytesDaImagem;
                    }
                    else
                    {
                        objVisitante.BinarioDoArquivoDeImagem = null;
                    }
a função acima retornava errado uma variavel do tipo byte[] so que somente com 13 posições no array, por que creio que eu estava pegando os bytes de um conteudo de bytes so que no padrão ToString(). Pois o indice de itens do array de bytes é bem alto tipo byte[5634] e na função acima sempre retornava byte[13] ou seja parte da imagem e por isso dava o Erro de 'Parametro Invalido' de tando pesquisar e usar o Breakpoint do Visual Studio analisando esta tarde linha a linha cheguei a esta conclusão que essa linha estava errado agora segue a função correta;
if (dbConn.Ler("BIN_IMG").ToString() != String.Empty)
                    {
                        byte[] BytesDaImagem = (byte[])dbConn.Ler("BIN_IMG");
                        objVisitante.BinarioDoArquivoDeImagem = BytesDaImagem;
                    }
                    else
                    {
                        objVisitante.BinarioDoArquivoDeImagem = null;
                    }
Veja que nesta linha simplemente dei um Cast '(byte[])dbConn.Ler("BIN_IMG");' ai funcionou de primeira. Bom mais uma empreitada finalizada depois de 2 dias de procura a solução. Valeu 'Xistyle' pela ajuda e ao pessoal deste forum. Segue alguns codigo de exemplo que podem ser uteis a outro programadores no dia a dia do projeto que estou fazendo.
/// <summary>
/// Converte a Imagem do tipo Image em byte[]
/// </summary>
/// <param name="_Imagem">Objeto do tipo Image</param>
/// <returns>Retorna objeto byte[]</returns>
public static byte[] ConverteImagemEmByteArray(Image _Imagem) 
{
    Image _ImagemClone = (Image)_Imagem.Clone();
    MemoryStream _Memoria = new MemoryStream();
    _ImagemClone.Save(_Memoria, System.Drawing.Imaging.ImageFormat.Jpeg);

    return (_Memoria.GetBuffer());
}

/// <summary>
/// Converte byte[] em Imagem do tipo Image
/// </summary>
/// <param name="_BytesDaImagem">Objeto do tipo byte[]</param>
/// <returns>Retorna objeto do tipo Image</returns>
public static Image ConverteByteArrayEmImagem(byte[] _BytesDaImagem)
{
    MemoryStream _Memoria = new MemoryStream(_BytesDaImagem);
    Image _Imagem = Image.FromStream(_Memoria);

    return (_Imagem);
}

/// <summary>
/// Converte byte[] em objeto do tipo Bitmap
/// </summary>
/// <param name="_BytesDaImagem">Objeto do tipo byte[]</param>
/// <returns>Retorna objeto do tipo Bitmap (Imagens que trabalham com mapeamento de Pixels)</returns>
public static Bitmap ConverteByteArrayEmBitmap(byte[] _BytesDaImagem) 
{
    MemoryStream _Memoria = new MemoryStream(_BytesDaImagem);
    _Memoria.Write(_BytesDaImagem, 0, _BytesDaImagem.Length);
    Bitmap _BitMap = new Bitmap(_Memoria);

    return (_BitMap);
}

Amigos ate a proxima Duvida !!! rrsss oubrigado mesmo...

Rodrigo

Contato: rodrigo_arf@hotmail.com

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Forum Statistics

    • Total Topics
      152.2k
    • Total Posts
      652k
×
×
  • Create New...