Як перетворити зображення в масив байтів


125

Хтось може підказати, як я можу перетворити зображення в байтовий масив і навпаки?

Я розробляю програму WPF та використовую зчитувач потоків.

Відповіді:


175

Зразок коду для зміни зображення в масив байтів

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

C # Зображення у масив байтів та масив байтів у клас перетворення зображень


12
замість System.Drawing.Imaging.ImageFormat.Gif, ви можете використовуватиimageIn.RawFormat
S.Serpooshan

1
Це не здається повторюваним, або, принаймні, через пару разів перетворення, починають виникати дивні помилки GDI +. ImageConverterЗнайдене рішення нижче , здається , щоб уникнути цих помилок.
Дейв Кузен

Можливо, краще зараз використовувати png.
Nyerguds

Зі сторони: це може містити додаткові метадані, які ви не хочете мати ;-) Щоб позбутися від метаданих, можливо, ви захочете створити нову растрову карту та передати їй зображення як би (new Bitmap(imageIn)).Save(ms, imageIn.RawFormat);.
Маркус Сафар

56

Для перетворення об’єкта зображення byte[]ви можете зробити наступне:

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

4
Ідеальний відповідь! .... немає потреби визначати "розширення файлу зображення", саме те, що я шукав.
Браво

1
Зі сторони: це може містити додаткові метадані, які ви не хочете мати ;-) Щоб позбутися від метаданих, можливо, ви захочете створити нову растрову карту та передати їй зображення як би .ConvertTo(new Bitmap(x), typeof(byte[]));.
Маркус Сафар

1
Для мене Visual Studio не розпізнає тип ImageConverter. Чи потрібна заява про імпорт, щоб використовувати це?
technoman23

32

Ще один спосіб отримати масив Byte з шляху зображення - це

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

Їх питання позначено тегом WPF (тому немає причин думати, що він працює на сервері і включають MapPath) І показує, що у них вже є зображення (немає причин читати його з диска, навіть не припускати, що це на диску для початку). Вибачте, але Ваша відповідь здається абсолютно неактуальною на питання
Ронан Тібаудау

19

Ось що я зараз використовую. Деякі з інших методів, які я спробував, були неоптимальними, оскільки вони змінювали глибину бітів пікселів (24-біт проти 32-бітових) або ігнорували роздільну здатність зображення (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();

Зображення в байтовому масиві:

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

Байтовий масив для зображення:

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

Редагувати: Щоб отримати зображення з jpg або png-файлу, слід прочитати файл у байтовому масиві за допомогою File.ReadAllBytes ():

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

Це дозволяє уникнути проблем, пов’язаних з Bitmap, які хочуть, щоб його вихідний потік залишався відкритим, і деякі запропоновані шляхи вирішення цієї проблеми, в результаті чого вихідний файл буде заблокований.


Під час тестування цього я б взяв отриманий растровий малюнок і перетворив його назад в байтовий масив, використовуючи: ImageConverter _imageConverter = new ImageConverter(); lock(SourceImage) { return (byte[])_imageConverter.ConvertTo(SourceImage, typeof(byte[])); } Там, де це буде переривчасто призводити до масивів двох різних розмірів. Це зазвичай трапляється після приблизно 100 ітерацій, але коли я отримую растрову карту, new Bitmap(SourceFileName);а потім запускаю її через цей код, вона працює добре.
Дон

@Don: Насправді немає хороших ідей. Чи послідовно, які зображення не дають такого ж виходу, як введення? Ви намагалися вивчити вихід, коли не так, як очікується, щоб зрозуміти, чому він різний? А може, це насправді не має значення, і можна просто прийняти, що "речі трапляються".
RenniePet

Це послідовно відбувалося. Причини так і не знайшли. У мене є відчуття, що це могло мати щось спільне з 4-байтною межею в розподілі пам'яті. Але це легко може бути неправильним. Я перейшов на використання MemoryStream з BinaryFormatter, і мені вдалося стати дуже послідовним, проте протестувавши понад 250 різних тестових зображень різного формату та розміру, циклічні в 1000 разів для перевірки. Дякую за відповідь
Дон

17

спробуйте це:

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 - це шлях до зображення чи все інше, як ми можемо передавати зображення в цьому
Шашанк

Це те, що я роблю в будь-який час, коли мені потрібно перетворити зображення в масив байтів або назад.
Алекс Ессільфі

Ви забули закрити потік пам'яті ... До речі, це скопійовано прямо з: посилання
Qwerty01

1
@ Qwerty01 Calling Dispose не очистить пам'ять, яку використовує MemoryStreamшвидше, принаймні в поточній реалізації. Насправді, якщо закрити його, ви не зможете скористатися Imageзгодом, ви отримаєте помилку GDI.
Saeb Amini

14

Ви можете використовувати File.ReadAllBytes()метод для читання будь-якого файлу в масив байтів. Щоб записати байтовий масив у файл, просто скористайтеся File.WriteAllBytes()методом.

Сподіваюся, це допомагає.

Ви можете знайти більше інформації та зразок коду тут .


Лише бічна примітка: Це може містити додаткові метадані, яких ви не хочете мати ;-)
Маркус Сафар

1
Може бути. Я писав цю відповідь 10 років тому, тоді я був свіжішим / нооб.
Шехар

5

Ви хочете лише пікселі або все зображення (включаючи заголовки) у вигляді байтового масиву?

Для пікселів: Використовуйте CopyPixelsметод на Bitmap. Щось на зразок:

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

Код:

using System.IO;

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

1
Працює лише в тому випадку, якщо він читає файл (і навіть тоді він отримує відформатовані / стиснуті байти, а не сирі, якщо це не BMP)
BradleyDotNET

3

Якщо ви не посилаєте imageBytes на перенесення байтів у потоці, метод нічого не поверне. Переконайтеся, що ви посилаєтеся на 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] Якщо ви все ще не бачите зображення в браузері, я написав докладний крок усунення несправностей

вирішено! -iis-not-serve-css, -images-and-javascript


1

Це Код для перетворення зображення будь-якого типу (наприклад, PNG, JPG, JPEG) у байтовий масив

   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
    }

Лише бічна примітка: Це може містити додаткові метадані, яких ви не хочете мати ;-)
Маркус Сафар

0

Для перетворення зображення в масив байтів. Код наведено нижче.

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

Для перетворення масиву байтів у зображення. Код наведено нижче. Код обробляється A Generic error occurred in GDI+у Збереження зображення.

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

Цей код отримує перші 100 рядків із таблиці в SQLSERVER 2012 і зберігає зображення в рядку як файл на локальному диску

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

    }

зверніть увагу: Каталог з іменем NewFolder повинен існувати в C: \


3
Ви відповіли неправильним запитанням ... Ну, я сподіваюсь ^ _ ^
JiBéDoublevé
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.