【问题标题】:How to convert image to byte array如何将图像转换为字节数组
【发布时间】:2011-04-17 14:35:10
【问题描述】:

谁能建议我如何将图像转换为字节数组,反之亦然?

我正在开发 WPF 应用程序并使用流阅读器。

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    将图像更改为字节数组的示例代码

    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 and Byte Array to Image Converter Class

    【讨论】:

    • 可以用System.Drawing.Imaging.ImageFormat.Gif代替imageIn.RawFormat
    • 这似乎不可重复,或者至少在转换几次之后,开始出现奇怪的 GDI+ 错误。下面找到的ImageConverter 解决方案似乎可以避免这些错误。
    • 现在使用 png 可能会更好。
    • 附带说明:这可能包含您不希望拥有的其他元数据;-) 要摆脱元数据,您可能需要创建一个 新位图并将 Image 传递给它,如 (new Bitmap(imageIn)).Save(ms, imageIn.RawFormat);.
    • 注意,MemoryStream不需要使用。可以像数组一样返回和使用MemoryStream。
    【解决方案2】:

    要将 Image 对象转换为byte[],您可以执行以下操作:

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

    【讨论】:

    • 完美答案!....无需定义“图像文件扩展名”,正是我想要的。
    • 附带说明:这可能包含您不希望拥有的其他元数据;-) 要摆脱元数据,您可能需要创建一个 新位图并将 Image 传递给它,如 .ConvertTo(new Bitmap(x), typeof(byte[]));.
    • 对我来说,Visual Studio 无法识别 ImageConverter 类型。是否需要导入语句才能使用它?
    • @technoman23 ImageConverter 是 System.Drawing 命名空间的一部分。
    • 那么,嗯,这实际上将图像转换为什么?这些字节里面是什么?
    【解决方案3】:

    另一种从图像路径获取字节数组的方法是

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

    【讨论】:

    • 他们的问题被标记为 WPF(因此没有理由认为它在服务器中运行并包含 MapPath)并且表明他们已经有了图像(没有理由从磁盘读取它,甚至假设它已打开磁盘开始)。很抱歉,您的回复似乎与问题完全无关
    【解决方案4】:

    这是我目前正在使用的。我尝试过的其他一些技术并不是最佳的,因为它们改变了像素的位深度(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));
    

    这避免了与希望其源流保持打开状态的位图相关的问题,以及一些针对导致源文件保持锁定的问题的建议解决方法。

    【讨论】:

    • 在对此进行测试期间,我将获取生成的位图并将其转换回字节数组,使用:ImageConverter _imageConverter = new ImageConverter(); lock(SourceImage) { return (byte[])_imageConverter.ConvertTo(SourceImage, typeof(byte[])); } 它会间歇性地生成 2 个不同大小的数组。这通常会在大约 100 次迭代后发生,但是当我使用 new Bitmap(SourceFileName); 获取位图然后通过该代码运行它时,它工作正常。
    • @Don:真的没有什么好主意。哪些图像不会产生与输入相同的输出是否一致?您是否尝试在输出与预期不符时检查输出以了解其不同之处?或者也许这并不重要,人们可以接受“事情发生了”。
    • 这种情况一直在发生。不过一直没找到原因。我有一种感觉,它可能与内存分配中的 4K 字节边界有关。但这很容易出错。我切换到使用带有 BinaryFormatter 的 MemoryStream,并且在使用超过 250 个不同格式和大小的不同测试图像进​​行测试时,我能够变得非常一致,循环超过 1000 次以进行验证。谢谢你的回复。
    【解决方案5】:

    试试这个:

    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 是图像路径或其他任何我们可以在其中传递图像的方式
    • 每当我需要将图像转换为字节数组或返回时,我都会这样做。
    • 您忘记关闭内存流...顺便说一句,这是直接复制自:link
    • @Qwerty01 调用 Dispose 不会更快地清理MemoryStream 使用的内存,至少在当前实现中是这样。事实上,如果你关闭它,之后你将无法使用Image,你会得到一个GDI错误。
    【解决方案6】:

    您可以使用File.ReadAllBytes() 方法将任何文件读入字节数组。要将字节数组写入文件,只需使用File.WriteAllBytes() 方法。

    希望这会有所帮助。

    您可以找到更多信息和示例代码here。

    【讨论】:

    • 附注:这可能包含您不希望拥有的其他元数据;-)
    • 也许吧。我在 10 年前写了这个答案,那时我还比较新鲜/菜鸟。
    【解决方案7】:

    您只想将像素或整个图像(包括标题)作为字节数组吗?

    对于像素:在位图上使用CopyPixels 方法。比如:

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

    【讨论】:

      【解决方案8】:

      如果您不引用 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
      

      【讨论】:

        【解决方案9】:

        代码:

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

        【讨论】:

        • 只有在读取文件时才有效(即使这样,他也会得到格式化/压缩的字节,而不是原始字节,除非它是 BMP)
        【解决方案10】:

        这是用于将任何类型(例如 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
            }
        

        【讨论】:

        • 附注:这可能包含您不希望拥有的其他元数据;-)
        【解决方案11】:

        将图像转换为字节数组。代码如下。

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

        将Byte数组转换为Image。代码如下。代码是Image Save中的句柄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();
            }
        }
        

        【讨论】:

          【解决方案12】:

          此代码从 SQLSERVER 2012 中的表中检索前 100 行,并将每行的图片保存为本地磁盘上的文件

           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:\

          【讨论】:

          • 你回答错了问题...好吧,我希望^_^
          猜你喜欢
          • 1970-01-01
          • 2011-06-01
          • 2023-03-09
          • 1970-01-01
          • 2021-07-17
          相关资源
          最近更新 更多