如何将图像转换为字节数组
Posted
技术标签:
【中文标题】如何将图像转换为字节数组【英文标题】:How to convert image to byte array 【发布时间】:2011-04-17 14:35:10 【问题描述】:谁能建议我,反之亦然?
我正在开发 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:\
【讨论】:
你回答错了问题...好吧,我希望^_^以上是关于如何将图像转换为字节数组的主要内容,如果未能解决你的问题,请参考以下文章