Bagaimana mengkonversi gambar ke array byte


125

Adakah yang bisa menyarankan bagaimana saya dapat mengubah gambar menjadi array byte dan sebaliknya?

Saya sedang mengembangkan aplikasi WPF dan menggunakan pembaca aliran.

Jawaban:


174

Kode contoh untuk mengubah gambar menjadi array 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 dan Byte Array to Image Converter Class


12
alih-alih System.Drawing.Imaging.ImageFormat.Gif, Anda dapat menggunakanimageIn.RawFormat
S.Serpooshan

1
Ini tampaknya tidak dapat diulang, atau setidaknya setelah beberapa kali pengubahan, kesalahan GDI + yang aneh mulai terjadi. The ImageConvertersolusi ditemukan di bawah tampaknya untuk menghindari kesalahan ini.
Dave Cousineau

Mungkin lebih baik menggunakan png, jaman sekarang.
Nyerguds

Di samping catatan: Ini mungkin berisi data meta tambahan yang tidak ingin Anda miliki ;-) Untuk menghapus metadata, Anda mungkin ingin membuat Bitmap baru dan meneruskan Gambar ke sana (new Bitmap(imageIn)).Save(ms, imageIn.RawFormat);.
Markus Safar

56

Untuk Mengonversi objek Gambar menjadi byte[]Anda dapat melakukan hal berikut:

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

4
Jawaban Sempurna! .... tidak perlu mendefinisikan "ekstensi file gambar", persis seperti yang saya cari.
Bravo

1
Di samping catatan: Ini mungkin berisi data meta tambahan yang tidak ingin Anda miliki ;-) Untuk menghapus metadata, Anda mungkin ingin membuat Bitmap baru dan meneruskan Gambar ke sana .ConvertTo(new Bitmap(x), typeof(byte[]));.
Markus Safar

1
Bagi saya Visual Studio tidak mengenali tipe ImageConverter. Apakah ada pernyataan impor yang diperlukan untuk menggunakan ini?
technoman23

32

Cara lain untuk mendapatkan array Byte dari jalur gambar adalah

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

Pertanyaan mereka diberi tag WPF (jadi tidak ada alasan untuk berpikir itu berjalan di server dan menyertakan MapPath) DAN menunjukkan bahwa mereka sudah memiliki gambar (tidak ada alasan untuk membacanya dari disk, bahkan tidak menganggapnya ada di disk untuk memulai). Maaf, tetapi balasan Anda tampaknya sama sekali tidak relevan dengan pertanyaan
Ronan Thibaudau

19

Inilah yang saya gunakan saat ini. Beberapa teknik lain yang saya coba tidak optimal karena mengubah kedalaman bit piksel (24-bit vs. 32-bit) atau mengabaikan resolusi gambar (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();

Array gambar ke 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();
     }
  }

Array byte ke Gambar:

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

Edit: Untuk mendapatkan Gambar dari file jpg atau png Anda harus membaca file tersebut ke dalam array byte menggunakan File.ReadAllBytes ():

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

Ini menghindari masalah yang terkait dengan Bitmap yang menginginkan aliran sumbernya tetap terbuka, dan beberapa solusi yang disarankan untuk masalah tersebut yang mengakibatkan file sumber tetap terkunci.


Selama pengujian ini, saya akan mengambil bitmap yang dihasilkan dan mengubahnya kembali menjadi array byte menggunakan: ImageConverter _imageConverter = new ImageConverter(); lock(SourceImage) { return (byte[])_imageConverter.ConvertTo(SourceImage, typeof(byte[])); } Di mana itu akan sesekali menghasilkan array dengan 2 ukuran berbeda. Ini biasanya akan terjadi setelah sekitar 100 iterasi, Tetapi ketika saya mendapatkan bitmap menggunakan new Bitmap(SourceFileName);dan kemudian menjalankannya melalui kode itu, itu berfungsi dengan baik.
Don

@ Don: Tidak benar-benar punya ide bagus. Apakah konsisten gambar mana yang tidak menghasilkan keluaran yang sama dengan masukan? Sudahkah Anda mencoba untuk memeriksa output ketika tidak seperti yang diharapkan untuk melihat mengapa berbeda? Atau mungkin itu tidak terlalu penting, dan seseorang dapat menerima begitu saja "sesuatu terjadi".
RenniePet

Itu terjadi secara konsisten. Tidak pernah ditemukan penyebabnya. Saya merasa itu mungkin ada hubungannya dengan batas 4K byte dalam alokasi memori. Tapi itu bisa saja salah. Saya beralih menggunakan MemoryStream dengan BinaryFormatter dan saya bisa menjadi sangat konsisten saat diuji dengan lebih dari 250 gambar uji yang berbeda dari berbagai format dan ukuran, diulang lebih dari 1000 kali untuk verifikasi. Terima kasih atas balasannya.
Don

17

coba ini:

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 adalah jalur gambar atau apa pun bagaimana kita bisa melewatkan gambar dalam hal ini
Shashank

Inilah yang saya lakukan kapan saja saya perlu mengonversi gambar menjadi array byte atau sebaliknya.
Alex Essilfie

Anda lupa menutup aliran memori ... btw ini disalin langsung dari: tautan
Qwerty01

1
@ Qwerty01 Calling Dispose tidak akan membersihkan memori yang digunakan oleh MemoryStreamlebih cepat, setidaknya dalam implementasi saat ini. Faktanya, jika Anda menutupnya, Anda tidak akan dapat menggunakan Imagesetelahnya, Anda akan mendapatkan kesalahan GDI.
Saeb Amini

14

Anda dapat menggunakan File.ReadAllBytes()metode untuk membaca file apa pun ke dalam array byte. Untuk menulis array byte ke dalam file, cukup gunakan File.WriteAllBytes()metode.

Semoga ini membantu.

Anda dapat menemukan informasi lebih lanjut dan kode contoh di sini .


Sekadar catatan: Ini mungkin berisi data meta tambahan yang tidak ingin Anda miliki ;-)
Markus Safar

1
Mungkin. Saya menulis jawaban ini 10 tahun yang lalu, saya lebih segar / noob saat itu.
Shekhar

5

Apakah Anda hanya menginginkan piksel atau seluruh gambar (termasuk header) sebagai array byte?

Untuk piksel: Gunakan CopyPixelsmetode di Bitmap. Sesuatu seperti:

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

Kode:

using System.IO;

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

1
Hanya berfungsi jika dia membaca file (dan bahkan kemudian dia mendapatkan byte yang diformat / dikompresi, bukan yang mentah kecuali itu adalah BMP)
BradleyDotNET

3

Jika Anda tidak mereferensikan imageBytes untuk membawa byte dalam aliran, metode tidak akan mengembalikan apa pun. Pastikan Anda mereferensikan 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] Jika Anda masih tidak melihat gambar di browser, saya menulis langkah pemecahan masalah mendetail

diselesaikan! -iis-not-serving-css, -images-and-javascript


1

Ini adalah Kode untuk mengubah gambar jenis apa pun (misalnya PNG, JPG, JPEG) menjadi array 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
    }

Sekadar catatan: Ini mungkin berisi data meta tambahan yang tidak ingin Anda miliki ;-)
Markus Safar

0

Untuk mengubah gambar menjadi array byte, kode diberikan di bawah ini.

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

Untuk mengubah array Byte ke Image Kode diberikan di bawah ini Kode ditangani A Generic error occurred in GDI+di 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

Kode ini mengambil 100 baris pertama dari tabel di SQLSERVER 2012 dan menyimpan gambar per baris sebagai file di disk lokal

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

    }

harap diperhatikan: Direktori dengan nama NewFolder harus ada di C: \


3
Anda menjawab pertanyaan yang salah ... Baiklah, saya harap ^ _ ^
JiBéDoublevé
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.