Byte Array para conversão de imagem

Eu quero converter uma matriz de bytes para uma imagem.

Este é o código do meu database de onde eu recebo a matriz de bytes:

public void Get_Finger_print() { try { using (SqlConnection thisConnection = new SqlConnection(@"Data Source=" + System.Environment.MachineName + "\\SQLEXPRESS;Initial Catalog=Image_Scanning;Integrated Security=SSPI ")) { thisConnection.Open(); string query = "select pic from Image_tbl";// where Name='" + name + "'"; SqlCommand cmd = new SqlCommand(query, thisConnection); byte[] image =(byte[]) cmd.ExecuteScalar(); Image newImage = byteArrayToImage(image); Picture.Image = newImage; //return image; } } catch (Exception) { } //return null; } 

Meu código de conversão:

 public Image byteArrayToImage(byte[] byteArrayIn) { try { MemoryStream ms = new MemoryStream(byteArrayIn,0,byteArrayIn.Length); ms.Write(byteArrayIn, 0, byteArrayIn.Length); returnImage = Image.FromStream(ms,true);//Exception occurs here } catch { } return returnImage; } 

Quando alcanço a linha com um comentário, ocorre a seguinte exceção: O Parameter is not valid.

Como posso consertar o que está causando essa exceção?

Você está gravando no seu stream de memory duas vezes, e também não está descartando o stream após o uso. Você também está pedindo ao decodificador de imagens para aplicar correção de cor incorporada.

Tente isso:

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

Talvez eu esteja perdendo alguma coisa, mas para mim este one-liner funciona bem com uma matriz de bytes que contém uma imagem de um arquivo JPEG.

 Image x = (Bitmap)((new ImageConverter()).ConvertFrom(jpegByteArray)); 

EDITAR:

Veja aqui para uma versão atualizada desta resposta: Como converter imagem em matriz de bytes

 public Image byteArrayToImage(byte[] bytesArr) { MemoryStream memstr = new MemoryStream(bytesArr); Image img = Image.FromStream(memstr); return img; } 

Eu gostaria de observar que há um bug na solução fornecida por @ isaias-b.

Essa solução assume que stride é igual ao tamanho da linha. Mas nem sempre é verdade. Devido aos alinhamentos de memory executados pelo GDI, o stride pode ser maior que o comprimento da linha. Isso deve ser levado em conta. Caso contrário, a imagem deslocada inválida será gerada. Os bytes de preenchimento em cada linha serão ignorados.

O stride é a largura de uma única linha de pixels (uma linha de varredura), arredondada para um limite de quatro bytes.

Código fixo:

 using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; public static class ImageExtensions { public static Image ImageFromRawBgraArray(this byte[] arr, int width, int height, PixelFormat pixelFormat) { var output = new Bitmap(width, height, pixelFormat); var rect = new Rectangle(0, 0, width, height); var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat); // Row-by-row copy var arrRowLength = width * Image.GetPixelFormatSize(output.PixelFormat) / 8; var ptr = bmpData.Scan0; for (var i = 0; i < height; i++) { Marshal.Copy(arr, i * arrRowLength, ptr, arrRowLength); ptr += bmpData.Stride; } output.UnlockBits(bmpData); return output; } } 

Para ilustrar a que isso pode levar, vamos gerar a imagem de gradiente 101x101 do PixelFormat.Format24bppRgb :

 var width = 101; var height = 101; var gradient = new byte[width * height * 3 /* bytes per pixel */]; for (int i = 0, pixel = 0; i < gradient.Length; i++, pixel = i / 3) { var x = pixel % height; var y = (pixel - x) / width; gradient[i] = (byte)((x / (double)(width - 1) + y / (double)(height - 1)) / 2d * 255); } 

Se bmpData.Scan0 array inteiro como está para o endereço apontado por bmpData.Scan0 , obteremos a seguinte imagem. Deslocamento de imagem porque parte da imagem foi gravada em bytes preenchidos, que foi ignorada. Também é por isso que a última linha está incompleta:

passo ignorado

Mas se bmpData.Stride ponteiro de destino de mudança de linha por linha pelo valor bmpData.Stride , uma imagem válida será gerada:

passo tomado em conta

Stride também pode ser negativo:

Se a passada for positiva, o bitmap será de cima para baixo. Se a passada for negativa, o bitmap será de baixo para cima.

Mas eu não trabalhei com essas imagens e isso está além da minha nota.

Resposta relacionada: C # - buffer RGB de bitmap diferente do C ++

Todas as respostas apresentadas assumem que a matriz de bytes contém dados em uma representação de formato de arquivo conhecida, como: gif, png ou jpg. Mas eu recentemente tive um problema ao tentar converter byte[] s, contendo informação linearizada BGRA, eficientemente em objects Image . O código a seguir resolve usando um object Bitmap .

 using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; public static class Extensions { public static Image ImageFromRawBgraArray( this byte[] arr, int width, int height) { var output = new Bitmap(width, height); var rect = new Rectangle(0, 0, width, height); var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat); var ptr = bmpData.Scan0; Marshal.Copy(arr, 0, ptr, arr.Length); output.UnlockBits(bmpData); return output; } } 

Esta é uma pequena variação de uma solução publicada neste site .

tente (ATUALIZAR)

 MemoryStream ms = new MemoryStream(byteArrayIn,0,byteArrayIn.Length); ms.Position = 0; // this is important returnImage = Image.FromStream(ms,true); 

Você não declarou returnImage como qualquer tipo de variável 🙂

Isso deve ajudar:

 public Image byteArrayToImage(byte[] byteArrayIn) { try { MemoryStream ms = new MemoryStream(byteArrayIn,0,byteArrayIn.Length); ms.Write(byteArrayIn, 0, byteArrayIn.Length); Image returnImage = Image.FromStream(ms,true); } catch { } return returnImage; } 

Isso é inspirado pela resposta de Holstebroe, além de comentários aqui: Obtendo um object Image de uma matriz de bytes

 Bitmap newBitmap; using (MemoryStream memoryStream = new MemoryStream(byteArrayIn)) using (Image newImage = Image.FromStream(memoryStream)) newBitmap = new Bitmap(newImage); return newBitmap; 

Há uma abordagem simples como abaixo, você pode usar o método FromStream de imagem para fazer o truque, lembre-se de usar System.Drawing;

 // using image object not file public byte[] imageToByteArray(Image imageIn) { MemoryStream ms = new MemoryStream(); imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif); return ms.ToArray(); } public Image byteArrayToImage(byte[] byteArrayIn) { MemoryStream ms = new MemoryStream(byteArrayIn); Image returnImage = Image.FromStream(ms); return returnImage; } 

Na maioria das vezes, quando isso acontece, são dados incorretos na coluna SQL. Esta é a maneira correta de inserir em uma coluna de imagem:

 INSERT INTO [TableX] (ImgColumn) VALUES ( (SELECT * FROM OPENROWSET(BULK N'C:\....\Picture 010.png', SINGLE_BLOB) as tempimg)) 

A maioria das pessoas faz isso de maneira incorreta:

 INSERT INTO [TableX] (ImgColumn) VALUES ('C:\....\Picture 010.png')) 

Eu encontrei esse caras Converter matriz para a imagem

  private void button1_Click(object sender, EventArgs e) { try { string hasil = "D:\\coba1000.jpg"; System.IO.File.WriteAllBytes(@hasil, bytestosend); pictureBox1.ImageLocation = @hasil; } catch { } }