Görüntüyü bayt dizisine dönüştürme


127

Bir görüntüyü bir bayt dizisine ve bunun tersini nasıl dönüştürebileceğimi kimse önerebilir mi?

Bir WPF uygulaması geliştiriyorum ve bir akış okuyucu kullanıyorum.

Yanıtlar:


176

Bir görüntüyü bayt dizisine dönüştürmek için örnek kod

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 ve Byte Array to Image Converter Sınıfı


12
bunun yerine System.Drawing.Imaging.ImageFormat.GifkullanabilirsinizimageIn.RawFormat
S.Serpooshan

1
Bu tekrarlanabilir görünmüyor veya en azından birkaç kez dönüştürmeden sonra garip GDI + hataları oluşmaya başlıyor. Aşağıda bulunan ImageConverterçözüm bu hatalardan kaçınıyor gibi görünüyor.
Dave Cousineau

Günümüzde png kullanmak daha iyi olabilir.
Nyerguds

Bir yan not: Bu, sahip olmak istemediğiniz ek meta verileri içerebilir ;-) Meta verilerden kurtulmak için yeni bir Bitmap oluşturup Görüntüyü iletmek isteyebilirsiniz. istediğiniz gibi(new Bitmap(imageIn)).Save(ms, imageIn.RawFormat); .
Markus Safar

56

Bir Görüntü nesnesini byte[]size dönüştürmek için aşağıdaki işlemleri yapabilirsiniz:

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

4
Mükemmel Cevap! .... Tam olarak aradığım "resim dosyası uzantısını" tanımlamaya gerek yok.
Bravo

1
Bir yan not: Bu, sahip olmak istemediğiniz ek meta verileri içerebilir ;-) Meta verilerden kurtulmak için, yeni bir Bitmap oluşturup Görüntüyü istediğiniz gibi iletmek isteyebilirsiniz .ConvertTo(new Bitmap(x), typeof(byte[]));.
Markus Safar

1
Benim için Visual Studio, ImageConverter türünü tanımıyor. Bunu kullanmak için gerekli olan bir ithalat beyanı var mı?
technoman23

32

Byte dizisini görüntü yolundan almanın başka bir yolu da

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

Soruları WPF olarak etiketlendi (bu nedenle, bir sunucuda çalıştığını ve bir MapPath içerdiğini düşünmek için bir neden yok) VE görüntüye zaten sahip olduklarını gösterir (diskten okumak için bir neden yok, hatta başlangıçta diskte olduğunu varsaymayın). Üzgünüm ama cevabınız soruyla tamamen alakasız görünüyor
Ronan Thibaudau

19

İşte şu anda kullandığım şey. Denediğim diğer tekniklerden bazıları, piksellerin bit derinliğini değiştirdikleri (24-bit vs. 32-bit) veya görüntünün çözünürlüğünü (dpi) göz ardı ettikleri için optimal değildi.

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

Bayt dizisine resim:

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

Byte dizisinden Image'e:

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

Düzenleme: Görüntüyü bir jpg veya png dosyasından almak için, dosyayı File.ReadAllBytes () kullanarak bir bayt dizisine okumalısınız:

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

Bu, Bitmap'in kaynak akışının açık tutulmasını istemesiyle ilgili sorunları önler ve bu soruna, kaynak dosyanın kilitli kalmasıyla sonuçlanan bazı geçici çözümler önerdi.


Bunun test edilmesi sırasında, elde edilen bit eşlemi alıp bir bayt dizisine geri döndürürdüm: ImageConverter _imageConverter = new ImageConverter(); lock(SourceImage) { return (byte[])_imageConverter.ConvertTo(SourceImage, typeof(byte[])); } Burada aralıklı olarak 2 farklı boyutta dizilerle sonuçlanırdı. Bu normalde yaklaşık 100 yinelemeden sonra olur, ancak bitmap'i kullanarak elde ettiğimde new Bitmap(SourceFileName);ve daha sonra bu kodla çalıştırdığımda iyi çalışıyor.
Don

@Don: Gerçekten iyi bir fikriniz yok. Hangi görüntülerin girdiyle aynı çıktıyı vermediği tutarlı mı? Beklendiği gibi olmadığında, neden farklı olduğunu görmek için çıktıyı incelemeye çalıştınız mı? Ya da belki gerçekten önemli değil ve kişi "şeylerin olduğunu" kabul edebilir.
RenniePet

Sürekli oluyordu. Nedeni asla bulamadım. Bellek ayırmada 4K bayt sınırıyla bir ilgisi olabileceğini hissediyorum. Ama bu kolaylıkla yanlış olabilir. Bir BinaryFormatter ile bir MemoryStream kullanmaya geçtim ve doğrulama için 1000 defadan fazla döngüye alınmış, çeşitli format ve boyutlarda 250'den fazla farklı test görüntüsüyle test edildiği gibi çok tutarlı hale geldim. Cevap için teşekkür ederim.
Don

17

bunu dene:

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 resim yolu veya başka bir şey bu görüntüyü geçebilir nasıl
Shashank

Bir görüntüyü bayt dizisine veya geri dönüştürmem gerektiğinde her zaman yaptığım şey budur.
Alex Essilfie


1
@ Qwerty01 Dispose Çağırmak MemoryStream, en azından mevcut uygulamada daha hızlı bir şekilde kullanılan belleği temizlemeyecektir . Aslında, kapatırsanız, Imagedaha sonra kullanamazsınız, bir GDI hatası alırsınız.
Saeb Amini

14

File.ReadAllBytes()Herhangi bir dosyayı bayt dizisine okumak için yöntemi kullanabilirsiniz . Bayt dizisini dosyaya yazmak için şunu kullanın:File.WriteAllBytes() yöntemi .

Bu yardımcı olur umarım.

Daha fazla bilgiyi ve örnek kodu burada bulabilirsiniz .


Sadece bir ek not: Bu, sahip olmak istemediğiniz ek meta verileri içerebilir ;-)
Markus Safar

1
Olabilir. Bu cevabı 10 yıl önce yazdım, o zamanlar daha tazeydim / çaylaktım.
Shekhar

5

Bir bayt dizisi olarak yalnızca pikselleri mi yoksa görüntünün tamamını (başlıklar dahil) mı istiyorsunuz?

Pikseller için: CopyPixelsBitmap'teki yöntemi kullanın . Gibi bir şey:

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

Kod:

using System.IO;

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

1
Yalnızca bir dosya okuyorsa çalışır (ve o zaman bile biçimlendirilmiş / sıkıştırılmış baytları alır, bir BMP değilse ham olanları
almaz

3

Akışta bayt taşımak için imageBytes'e başvurmazsanız, yöntem hiçbir şey döndürmez. İmageBytes = 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] Görüntüyü tarayıcıda hala göremiyorsanız, ayrıntılı bir sorun giderme adımı yazdım

çözüldü! ııs-not-hizmet-css,-ve-javascript -resimlerinizi


1

Bu, herhangi bir türdeki görüntüyü (örneğin PNG, JPG, JPEG) bayt dizisine dönüştürmek için koddur.

   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
    }

Sadece bir ek not: Bu, sahip olmak istemediğiniz ek meta verileri içerebilir ;-)
Markus Safar

0

Görüntüyü bayt dizisine dönüştürmek için kod aşağıda verilmiştir.

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

Byte dizisini Image'a dönüştürmek için kod aşağıda verilmiştir. Kod A Generic error occurred in GDI+Image Save'de tutulur .

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

Bu kod SQLSERVER 2012'deki tablodan ilk 100 satırı alır ve yerel diskte dosya olarak satır başına bir resim kaydeder

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

    }

lütfen unutmayın: NewFolder isimli dizin C: \ içinde bulunmalıdır.


3
Yanlış soruyu cevapladınız ... Umarım ^ _ ^
JiBéDoublevé
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.