如何将图像转换为字节数组


125

有人可以建议我如何将图像转换为字节数组,反之亦然?

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

Answers:


174

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

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找到的解决方案似乎避免了这些错误。
Dave Cousineau

如今最好使用png。
Nyerguds

附带说明:这可能包含您不想要的其他元数据;-)要摆脱元数据,您可能想要创建一个新的Bitmap并将Image传递给它(new Bitmap(imageIn)).Save(ms, imageIn.RawFormat);
Markus Safar,

56

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

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

4
完美答案!....无需定义“图像文件扩展名”,正是我想要的。
Bravo 2013年

1
附带说明:这可能包含您不想要的其他元数据;-)要摆脱元数据,您可能想要创建一个新的Bitmap并将Image传递给它.ConvertTo(new Bitmap(x), typeof(byte[]));
Markus Safar,

1
对我来说,Visual Studio无法识别ImageConverter类型。是否需要使用导入语句才能使用此语句?
technoman23

32

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

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

他们的问题被标记为WPF(因此没有理由认为它正在服务器中运行并包含MapPath)并显示他们已经拥有该图像(没有理由从磁盘读取它,甚至不假设它从磁盘上开始)。抱歉,您的答复似乎与问题完全无关
Ronan Thibaudau

18

这是我目前正在使用的。我尝试过的其他一些技术并不是最优的,因为它们改变了像素的位深(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[])); } 在其中将间歇性地生成2种不同大小的数组的情况。通常在大约100次迭代后会发生这种情况,但是当我使用获取位图new Bitmap(SourceFileName);然后通过该代码运行它时,它就可以正常工作。

@Don:真的没有什么好主意。哪些图像不会产生与输入相同的输出是否一致?您是否尝试过检查输出结果与预期不符的原因,以了解其不同之处?也许这并不重要,人们可以接受“发生的事情”。
RenniePet '16

它一直在发生。虽然从未找到原因。我感觉它可能与内存分配中的4K字节边界有关。但这很容易是错误的。我转而将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是图像路径或其他我们可以如何在其中传递图像的方法
Shashank 2010年

这是我需要将图像转换为字节数组或返回字节数组时所做的一切。
Alex Essilfie

您忘了关闭内存流了……顺便说一句,它直接从以下位置复制:link
Qwerty01'2

1
@ Qwerty01调用Dispose不会MemoryStream更快地清理内存,至少在当前实现中是如此。实际上,如果将其关闭,则以后将无法使用Image,将收到GDI错误。
Saeb Amini

14

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

希望这可以帮助。

您可以在此处找到更多信息和示例代码。


附带说明:这可能包含您不想要的其他元数据;-)
Markus Safar

1
也许。我10年前写了这个答案,那时我还很新鲜。
Shekhar

5

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

对于像素:使用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); 

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不提供CSS,图像和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
    }

附带说明:这可能包含您不想要的其他元数据;-)
Markus Safar

0

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

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

要将Byte数组转换为Image,代码如下所示,该代码A Generic error occurred in GDI+在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

此代码从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:\


3
你回答错误的问题......嗯,我希望^ _ ^
JiBéDoublevé
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.