Byte Array to Image Conversion

Voglio convertire un array di byte in un’immagine.

Questo è il mio codice di database da dove ottengo l’array di byte:

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; } 

Il mio codice di conversione:

 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 raggiungo la linea con un commento, si verifica la seguente eccezione: Il Parameter is not valid.

Come posso risolvere ciò che sta causando questa eccezione?

    Stai scrivendo sul tuo stream di memoria due volte, inoltre non stai eliminando il stream dopo l’uso. Stai anche chiedendo al decodificatore di immagini di applicare la correzione del colore incorporata.

    Prova questo invece:

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

    Forse mi manca qualcosa, ma per me questa one-liner funziona bene con un array di byte che contiene un’immagine di un file JPEG.

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

    MODIFICARE:

    Vedi qui per una versione aggiornata di questa risposta: Come convertire l’immagine in array di byte

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

    Vorrei notare che c’è un bug nella soluzione fornito da @ isaias-b.

    Questa soluzione presuppone che la stride sia uguale alla lunghezza della fila. Ma non è sempre vero. A causa degli allineamenti di memoria eseguiti da GDI, lo stride può essere maggiore della lunghezza della riga. Questo deve essere preso in considerazione. Altrimenti verrà generata un’immagine spostata non valida. I byte di riempimento in ogni riga verranno ignorati.

    La falcata è la larghezza di una singola riga di pixel (una linea di scansione), arrotondata ad un limite di quattro byte.

    Codice fisso:

     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; } } 

    Per illustrare a cosa può portare, PixelFormat.Format24bppRgb immagine del gradiente PixelFormat.Format24bppRgb 101x101:

     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 dovessimo copiare l'intero array così com'è all'indirizzo indirizzato da bmpData.Scan0 , otterremo l'immagine seguente. Spostamento dell'immagine perché parte dell'immagine è stata scritta in byte di riempimento, che è stata ignorata. Anche per questo motivo l'ultima riga è incompleta:

    falcata ignorata

    Ma se copiamo il puntatore di destinazione spostamento riga per riga in base bmpData.Stride valore bmpData.Stride , verrà generato un file immagine valido:

    passo preso in considerazione

    Anche Stride può essere negativo:

    Se la falcata è positiva, la bitmap è top-down. Se la falcata è negativa, la bitmap è dal basso verso l'alto.

    Ma non ho lavorato con queste immagini e questo è oltre la mia nota.

    Risposta correlata: C # - Buffer RGB da Bitmap diverso da C ++

    Tutte le risposte presentate presuppongono che la matrice di byte contenga dati in una rappresentazione di formato di file noto, come: gif, png o jpg. Ma recentemente ho avuto un problema nel tentativo di convertire i byte[] s, contenenti informazioni BGRA linearizzate, in modo efficiente negli oggetti Image . Il seguente codice lo risolve usando un 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; } } 

    Questa è una variante leggermente diversa di una soluzione che è stata pubblicata su questo sito .

    prova (AGGIORNA)

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

    c’è un approccio semplice come sotto, è ansible utilizzare il metodo FromStream di immagine per fare il trucco, Basta ricordare di usare 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; } 

    Non hai dichiarato returnImage come qualsiasi tipo di variabile 🙂

    Questo dovrebbe aiutare:

     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; } 

    Questo è ispirato alla risposta di Holstebroe, oltre ai commenti qui: Ottenere un object Immagine da un array di byte

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

    La maggior parte delle volte in cui ciò accade, si tratta di dati non validi nella colonna SQL. Questo è il modo corretto di inserire in una colonna di immagini:

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

    La maggior parte delle persone lo fa in modo non corretto in questo modo:

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

    Ho trovato questo ragazzi Converti array in immagine

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