Come convertire un'immagine in un array di byte


125

Qualcuno può suggerire come posso convertire un'immagine in un array di byte e viceversa?

Sto sviluppando un'applicazione WPF e utilizzo un lettore di flussi.

Risposte:


174

Codice di esempio per modificare un'immagine in una matrice di byte

public byte[] ImageToByteArray(System.Drawing.Image imageIn)
{
   using (var ms = new MemoryStream())
   {
      imageIn.Save(ms,imageIn.RawFormat);
      return  ms.ToArray();
   }
}

C # Image to Byte Array e Byte Array to Image Converter Class


12
invece di System.Drawing.Imaging.ImageFormat.Gif, puoi usareimageIn.RawFormat
S.Serpooshan

1
Ciò non sembra essere ripetibile, o almeno dopo un paio di volte di conversione, iniziano a verificarsi strani errori GDI +. La ImageConvertersoluzione trovata di seguito sembra evitare questi errori.
Dave Cousineau

Potrebbe essere meglio usare png, al giorno d'oggi.
Nyerguds

Su un lato nota: questo potrebbe contenere i metadati aggiuntivi che non si desidera avere ;-) Per sbarazzarsi dei metadati si potrebbe desiderare di creare una nuova bitmap e passare l' immagine ad esso come (new Bitmap(imageIn)).Save(ms, imageIn.RawFormat);.
Markus Safar

56

Per convertire un oggetto Immagine in byte[]puoi fare come segue:

public static byte[] converterDemo(Image x)
{
    ImageConverter _imageConverter = new ImageConverter();
    byte[] xByte = (byte[])_imageConverter.ConvertTo(x, typeof(byte[]));
    return xByte;
}

4
Risposta perfetta! .... non c'è bisogno di definire l '"estensione del file immagine", esattamente quello che stavo cercando.
Bravo

1
Su un lato nota: questo potrebbe contenere i metadati aggiuntivi che non si desidera avere ;-) Per sbarazzarsi dei metadati si potrebbe desiderare di creare una nuova bitmap e passare l' immagine ad esso come .ConvertTo(new Bitmap(x), typeof(byte[]));.
Markus Safar

1
Per me Visual Studio non riconosce il tipo ImageConverter. C'è un'istruzione di importazione necessaria per usarlo?
technoman23

32

Un altro modo per ottenere l'array Byte dal percorso dell'immagine è

byte[] imgdata = System.IO.File.ReadAllBytes(HttpContext.Current.Server.MapPath(path));

La loro domanda è contrassegnata come WPF (quindi non c'è motivo di pensare che sia in esecuzione su un server e includere un MapPath) E mostra che hanno già l'immagine (nessun motivo per leggerla dal disco, nemmeno presumere che sia sul disco per cominciare). Mi dispiace ma la tua risposta sembra completamente irrilevante alla domanda
Ronan Thibaudau

19

Ecco cosa sto usando attualmente. Alcune delle altre tecniche che ho provato non sono state ottimali perché hanno cambiato la profondità di bit dei pixel (24 bit contro 32 bit) o ​​hanno ignorato la risoluzione dell'immagine (dpi).

  // ImageConverter object used to convert byte arrays containing JPEG or PNG file images into 
  //  Bitmap objects. This is static and only gets instantiated once.
  private static readonly ImageConverter _imageConverter = new ImageConverter();

Da immagine a matrice di byte:

  /// <summary>
  /// Method to "convert" an Image object into a byte array, formatted in PNG file format, which 
  /// provides lossless compression. This can be used together with the GetImageFromByteArray() 
  /// method to provide a kind of serialization / deserialization. 
  /// </summary>
  /// <param name="theImage">Image object, must be convertable to PNG format</param>
  /// <returns>byte array image of a PNG file containing the image</returns>
  public static byte[] CopyImageToByteArray(Image theImage)
  {
     using (MemoryStream memoryStream = new MemoryStream())
     {
        theImage.Save(memoryStream, ImageFormat.Png);
        return memoryStream.ToArray();
     }
  }

Matrice di byte in immagine:

  /// <summary>
  /// Method that uses the ImageConverter object in .Net Framework to convert a byte array, 
  /// presumably containing a JPEG or PNG file image, into a Bitmap object, which can also be 
  /// used as an Image object.
  /// </summary>
  /// <param name="byteArray">byte array containing JPEG or PNG file image or similar</param>
  /// <returns>Bitmap object if it works, else exception is thrown</returns>
  public static Bitmap GetImageFromByteArray(byte[] byteArray)
  {
     Bitmap bm = (Bitmap)_imageConverter.ConvertFrom(byteArray);

     if (bm != null && (bm.HorizontalResolution != (int)bm.HorizontalResolution ||
                        bm.VerticalResolution != (int)bm.VerticalResolution))
     {
        // Correct a strange glitch that has been observed in the test program when converting 
        //  from a PNG file image created by CopyImageToByteArray() - the dpi value "drifts" 
        //  slightly away from the nominal integer value
        bm.SetResolution((int)(bm.HorizontalResolution + 0.5f), 
                         (int)(bm.VerticalResolution + 0.5f));
     }

     return bm;
  }

Modifica: per ottenere l'immagine da un file jpg o png devi leggere il file in un array di byte usando File.ReadAllBytes ():

 Bitmap newBitmap = GetImageFromByteArray(File.ReadAllBytes(fileName));

Ciò evita i problemi relativi a Bitmap che desidera che il suo flusso di origine venga mantenuto aperto e alcune soluzioni alternative suggerite a quel problema che comportano il blocco del file di origine.


Durante il test di questo, prenderei la bitmap risultante e la trasformerei di nuovo in un array di byte usando: ImageConverter _imageConverter = new ImageConverter(); lock(SourceImage) { return (byte[])_imageConverter.ConvertTo(SourceImage, typeof(byte[])); } Dove risulterebbe in modo intermittente in array di 2 diverse dimensioni. Questo normalmente accadrebbe dopo circa 100 iterazioni, ma quando ottengo la bitmap usando new Bitmap(SourceFileName);e poi la eseguo attraverso quel codice funziona bene.
Don

@Don: Non ho davvero buone idee. È coerente quali immagini non producono lo stesso output dell'input? Hai provato a esaminare l'output quando non è come previsto per vedere perché è diverso? O forse non ha molta importanza, e si può semplicemente accettare che "le cose accadano".
RenniePet

Stava accadendo costantemente. Non ho mai trovato la causa però. Ho la sensazione che potrebbe aver avuto qualcosa a che fare con un limite di 4K byte nell'allocazione della memoria. Ma potrebbe essere facilmente sbagliato. Sono passato a utilizzare un MemoryStream con un BinaryFormatter e sono stato in grado di diventare molto coerente durante il test con oltre 250 diverse immagini di prova di diversi formati e dimensioni, ripetute più di 1000 volte per la verifica. Grazie per la risposta.
Don

17

prova questo:

public byte[] imageToByteArray(System.Drawing.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;
}

imageToByteArray (System.Drawing.Image imageIn) imageIn è il percorso dell'immagine o qualsiasi altra cosa su come possiamo passare l'immagine in questo
Shashank,

Questo è quello che faccio ogni volta che ho bisogno di convertire un'immagine in un array di byte o viceversa.
Alex Essilfie

Hai dimenticato di chiudere il memorystream ... btw questo è stato copiato direttamente da: link
Qwerty01

1
@ Qwerty01 La chiamata a Dispose non pulirà MemoryStreampiù velocemente la memoria utilizzata da nessuno, almeno nell'attuale implementazione. Infatti, se lo chiudi, non sarai in grado di usare il Imagedopo, otterrai un errore GDI.
Saeb Amini

14

È possibile utilizzare il File.ReadAllBytes()metodo per leggere qualsiasi file nell'array di byte. Per scrivere un array di byte in un file, usa semplicemente il File.WriteAllBytes()metodo.

Spero che questo ti aiuti.

Puoi trovare ulteriori informazioni e codice di esempio qui .


Solo una nota a margine: questo potrebbe contenere metadati aggiuntivi che non vuoi avere ;-)
Markus Safar

1
Può essere. Ho scritto questa risposta 10 anni fa, allora ero più fresco / noob.
Shekhar

5

Vuoi solo i pixel o l'intera immagine (comprese le intestazioni) come un array di byte?

Per i pixel: usa il CopyPixelsmetodo su Bitmap. Qualcosa di simile a:

var bitmap = new BitmapImage(uri);

//Pixel array
byte[] pixels = new byte[width * height * 4]; //account for stride if necessary and whether the image is 32 bit, 16 bit etc.

bitmap.CopyPixels(..size, pixels, fullStride, 0); 

3

Codice:

using System.IO;

byte[] img = File.ReadAllBytes(openFileDialog1.FileName);

1
Funziona solo se sta leggendo un file (e anche in questo caso ottiene i byte formattati / compressi, non quelli grezzi a meno che non sia un BMP)
BradleyDotNET

3

Se non fai riferimento a imageBytes per trasportare i byte nel flusso, il metodo non restituirà nulla. Assicurati di fare riferimento a imageBytes = m.ToArray ();

    public static byte[] SerializeImage() {
        MemoryStream m;
        string PicPath = pathToImage";

        byte[] imageBytes;
        using (Image image = Image.FromFile(PicPath)) {

            using ( m = new MemoryStream()) {

                image.Save(m, image.RawFormat);
                imageBytes = new byte[m.Length];
               //Very Important    
               imageBytes = m.ToArray();

            }//end using
        }//end using

        return imageBytes;
    }//SerializeImage

[NB] Se ancora non vedi l'immagine nel browser ho scritto un passo dettagliato per la risoluzione dei problemi

risolto! -iis-non-serving-css, -Le immagini-e-javascript


1

Questo è il codice per convertire l'immagine di qualsiasi tipo (ad esempio PNG, JPG, JPEG) in un array di byte

   public static byte[] imageConversion(string imageName){            


        //Initialize a file stream to read the image file
        FileStream fs = new FileStream(imageName, FileMode.Open, FileAccess.Read);

        //Initialize a byte array with size of stream
        byte[] imgByteArr = new byte[fs.Length];

        //Read data from the file stream and put into the byte array
        fs.Read(imgByteArr, 0, Convert.ToInt32(fs.Length));

        //Close a file stream
        fs.Close();

        return imageByteArr
    }

Solo una nota a margine: questo potrebbe contenere metadati aggiuntivi che non vuoi avere ;-)
Markus Safar

0

Per convertire l'immagine in array di byte. Il codice è dato di seguito.

public byte[] ImageToByteArray(System.Drawing.Image images)
{
   using (var _memorystream = new MemoryStream())
   {
      images.Save(_memorystream ,images.RawFormat);
      return  _memorystream .ToArray();
   }
}

Per convertire l'array Byte in immagine. Il codice è dato di seguito. Il codice è gestito A Generic error occurred in GDI+in Image Save.

public void SaveImage(string base64String, string filepath)
{
    // image convert to base64string is base64String 
    //File path is which path to save the image.
    var bytess = Convert.FromBase64String(base64String);
    using (var imageFile = new FileStream(filepath, FileMode.Create))
    {
        imageFile.Write(bytess, 0, bytess.Length);
        imageFile.Flush();
    }
}

-2

Questo codice recupera le prime 100 righe dalla tabella in SQLSERVER 2012 e salva un'immagine per riga come file su disco locale

 public void SavePicture()
    {
        SqlConnection con = new SqlConnection("Data Source=localhost;Integrated security=true;database=databasename");
        SqlDataAdapter da = new SqlDataAdapter("select top 100 [Name] ,[Picture] From tablename", con);
        SqlCommandBuilder MyCB = new SqlCommandBuilder(da);
        DataSet ds = new DataSet("tablename");
        byte[] MyData = new byte[0];
        da.Fill(ds, "tablename");
        DataTable table = ds.Tables["tablename"];
           for (int i = 0; i < table.Rows.Count;i++ )               
               {
                DataRow myRow;
                myRow = ds.Tables["tablename"].Rows[i];
                MyData = (byte[])myRow["Picture"];
                int ArraySize = new int();
                ArraySize = MyData.GetUpperBound(0);
                FileStream fs = new FileStream(@"C:\NewFolder\" + myRow["Name"].ToString() + ".jpg", FileMode.OpenOrCreate, FileAccess.Write);
                fs.Write(MyData, 0, ArraySize);
                fs.Close();
               }

    }

nota: la directory con il nome NewFolder dovrebbe esistere in C: \


3
Hai risposto alla domanda sbagliata ... Beh, spero ^ _ ^
JiBéDoublevé
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.