Ir para conteúdo
Fórum Script Brasil
  • 0

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


rodrigo_arf

Pergunta

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 para o comentário
Compartilhar em outros sites

10 respostass a esta questão

Posts Recomendados

  • 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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;
}

Editado por Xistyle
Link para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...