Cách chuyển đổi hình ảnh sang mảng byte


125

Ai đó có thể đề xuất cách tôi có thể chuyển đổi một hình ảnh thành một mảng byte và ngược lại không?

Tôi đang phát triển ứng dụng WPF và sử dụng trình đọc luồng.

Câu trả lời:


174

Mã mẫu để thay đổi hình ảnh thành một mảng 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 và Byte Array to Image Converter Class


12
thay vì System.Drawing.Imaging.ImageFormat.Gif, bạn có thể sử dụngimageIn.RawFormat
S.Serpooshan

1
Điều này dường như không thể lặp lại, hoặc ít nhất sau một vài lần chuyển đổi, các lỗi GDI + kỳ lạ bắt đầu xảy ra. Các ImageConvertergiải pháp phát hiện bên dưới dường như để tránh các lỗi này.
Dave Cousineau

Có thể tốt hơn khi sử dụng png, bây giờ.
Nyerguds

Một lưu ý nhỏ: Điều này có thể chứa dữ liệu meta bổ sung mà bạn không muốn có ;-) Để loại bỏ siêu dữ liệu, bạn có thể muốn tạo một Bitmap mới và chuyển Hình ảnh cho nó (new Bitmap(imageIn)).Save(ms, imageIn.RawFormat);.
Markus Safar

56

Để Chuyển đổi một đối tượng Hình ảnh sang, byte[]bạn có thể làm như sau:

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

4
Câu trả lời hoàn hảo! .... không cần xác định "phần mở rộng tệp hình ảnh", chính xác những gì tôi đang tìm kiếm.
Bravo

1
Một lưu ý nhỏ: Điều này có thể chứa dữ liệu meta bổ sung mà bạn không muốn có ;-) Để loại bỏ siêu dữ liệu, bạn có thể muốn tạo một Bitmap mới và chuyển Hình ảnh cho nó .ConvertTo(new Bitmap(x), typeof(byte[]));.
Markus Safar

1
Đối với tôi Visual Studio không nhận dạng được loại ImageConverter. Có cần có một câu lệnh nhập để sử dụng điều này không?
technoman23

32

Một cách khác để lấy mảng Byte từ đường dẫn hình ảnh là

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

Câu hỏi của họ được gắn thẻ WPF (vì vậy không có lý do gì để nghĩ rằng nó đang chạy trong một máy chủ và bao gồm một MapPath) VÀ cho thấy họ đã có hình ảnh (không có lý do gì để đọc nó từ đĩa, thậm chí không cho rằng nó trên đĩa để bắt đầu). Tôi xin lỗi nhưng câu trả lời của bạn dường như hoàn toàn không liên quan đến câu hỏi
Ronan Thibaudau

19

Đây là những gì tôi hiện đang sử dụng. Một số kỹ thuật khác mà tôi đã thử không tối ưu vì chúng đã thay đổi độ sâu bit của pixel (24-bit so với 32-bit) hoặc bỏ qua độ phân giải của hình ảnh (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();

Hình ảnh thành mảng 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();
     }
  }

Mảng Byte thành Hình ảnh:

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

Chỉnh sửa: Để lấy Hình ảnh từ tệp jpg hoặc png, bạn nên đọc tệp thành một mảng byte bằng cách sử dụng File.ReadAllBytes ():

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

Điều này tránh các sự cố liên quan đến việc Bitmap muốn luồng nguồn của nó được giữ ở trạng thái mở và một số cách giải quyết được đề xuất cho vấn đề đó dẫn đến việc tệp nguồn bị khóa.


Trong quá trình thử nghiệm điều này, tôi sẽ lấy bitmap kết quả và biến nó trở lại thành một mảng byte bằng cách sử dụng: ImageConverter _imageConverter = new ImageConverter(); lock(SourceImage) { return (byte[])_imageConverter.ConvertTo(SourceImage, typeof(byte[])); } Nơi nó sẽ dẫn đến các mảng có 2 kích thước khác nhau không liên tục. Điều này thường xảy ra sau khoảng 100 lần lặp, nhưng khi tôi lấy bitmap bằng cách sử dụng new Bitmap(SourceFileName);và sau đó chạy nó thông qua mã đó, nó hoạt động tốt.
Don

@Don: Không thực sự có bất kỳ ý tưởng hay. Có nhất quán hình ảnh nào không dẫn đến đầu ra giống như đầu vào không? Bạn đã thử kiểm tra kết quả đầu ra khi nó không như mong đợi để xem tại sao nó lại khác biệt? Hoặc có thể nó không thực sự quan trọng, và người ta chỉ có thể chấp nhận rằng "mọi thứ xảy ra".
RenniePet

Nó đã liên tục xảy ra. Không bao giờ tìm thấy nguyên nhân mặc dù. Tôi có cảm giác nó có thể liên quan đến ranh giới byte 4K trong phân bổ bộ nhớ. Nhưng điều đó có thể dễ dàng sai. Tôi đã chuyển sang sử dụng MemoryStream với BinaryFormatter và tôi đã có thể trở nên rất nhất quán khi được thử nghiệm với hơn 250 hình ảnh thử nghiệm khác nhau với các định dạng và kích thước khác nhau, được lặp lại hơn 1000 lần để xác minh. Cảm ơn bạn đã trả lời.
Don

17

thử cái này:

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 là con đường hình ảnh hoặc bất cứ thứ gì như thế nào chúng ta có thể vượt qua hình ảnh trong này
Shashank

Đây là những gì tôi làm bất cứ lúc nào tôi cần chuyển đổi một hình ảnh thành một mảng byte hoặc trở lại.
Alex Essilfie

Bạn quên đóng MemoryStream ... btw này được sao chép trực tiếp từ: liên kết
Qwerty01

1
@ Qwerty01 Gọi tắt sẽ không làm sạch bộ nhớ được sử dụng MemoryStreamnhanh hơn, ít nhất là trong quá trình triển khai hiện tại. Trên thực tế, nếu bạn đóng nó, bạn sẽ không thể sử dụng Imagesau đó, bạn sẽ gặp lỗi GDI.
Saeb Amini

14

Bạn có thể sử dụng File.ReadAllBytes()phương thức để đọc bất kỳ tệp nào thành mảng byte. Để ghi mảng byte vào tệp, chỉ cần sử dụng File.WriteAllBytes()phương thức.

Hi vọng điêu nay co ich.

Bạn có thể tìm thêm thông tin và mã mẫu tại đây .


Chỉ là một lưu ý phụ: Điều này có thể chứa dữ liệu meta bổ sung mà bạn không muốn có ;-)
Markus Safar

1
Có lẽ. Tôi đã viết câu trả lời này cách đây 10 năm, hồi đó tôi tươi tỉnh hơn / noob.
Shekhar

5

Bạn chỉ muốn các pixel hoặc toàn bộ hình ảnh (bao gồm cả tiêu đề) dưới dạng một mảng byte?

Đối với pixel: Sử dụng CopyPixelsphương pháp trên Bitmap. Cái gì đó như:

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

Mã:

using System.IO;

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

1
Chỉ hoạt động nếu ông đang đọc một tập tin (và thậm chí sau đó anh nhận được các định dạng / byte nén, không phải là những nguyên trừ một BMP của nó)
BradleyDotNET

3

Nếu bạn không tham chiếu imageBytes để mang các byte trong luồng, phương thức sẽ không trả về bất kỳ thứ gì. Đảm bảo rằng bạn tham chiếu 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] Nếu bạn vẫn không thấy hình ảnh trong trình duyệt, tôi đã viết một bước khắc phục sự cố chi tiết

đã giải quyết! -iis-not-serve-css, -images-and-javascript


1

Đây là Mã để chuyển đổi hình ảnh của bất kỳ loại nào (ví dụ: PNG, JPG, JPEG) thành mảng 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
    }

Chỉ là một lưu ý phụ: Điều này có thể chứa dữ liệu meta bổ sung mà bạn không muốn có ;-)
Markus Safar

0

Để chuyển đổi hình ảnh thành mảng byte, mã được cung cấp bên dưới.

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

Để chuyển đổi mảng Byte thành Image, mã được đưa ra bên dưới, mã được xử lý A Generic error occurred in GDI+trong 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

Mã này truy xuất 100 hàng đầu tiên từ bảng trong SQLSERVER 2012 và lưu ảnh trên mỗi hàng dưới dạng tệp trên đĩa cục bộ

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

    }

xin lưu ý: Thư mục có tên NewFolder phải tồn tại trong C: \


3
Bạn đã trả lời sai câu hỏi ... Chà, tôi hy vọng ^ _ ^
JiBéDoublevé
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.