功能需求
1、把一张图片(png bmp jpeg bmp gif)转换为byte数组在内存中操作。
2、把内存中的byte数组转换成Image对象,赋值给相应的控件显示。
3、从图片byte数组得到对应的图片格式,生成一张图片保存到磁盘中。
这个的Image是System.Drawing.Image。
//Get an image from file Image image = Image.FromFile("D:\test.jpg"); Bitmap bitmap = new Bitmap("D:\test.jpg");
一下三个函数分别实现了上述三个需求:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing.Imaging; using System.Drawing; using System.IO; namespace NetUtilityLib { public class ImageHelper { /// <summary> /// Convert Image to Byte[] /// </summary> /// <param name="image"></param> /// <returns></returns> public static byte[] ImageToBytes(Image image) { ImageFormat format = image.RawFormat; using (MemoryStream ms = new MemoryStream()) { //复杂一点的判断 //if(format.Equals(ImageFormat.Jpeg)) //{ // image.Save(ms, ImageFormat.Jpeg); //} //else if (format.Equals(ImageFormat.Png)) //{ // image.Save(ms, ImageFormat.Png); //} //else if(format.Equals(ImageFormat.Bmp)) //{ // image.Save(ms, ImageFormat.Bmp); //} //else if (format.Equals(ImageFormat.Gif)) //{ // image.Save(ms, ImageFormat.Gif); //} //else if (format.Equals(ImageFormat.Icon)) //{ // image.Save(ms, ImageFormat.Icon); //} //直接搞定 image.Save(ms, format); byte[] buffer = new byte[ms.Length]; //Image.Save()会改变MemoryStream的Position,需要重新Seek到Begin也就是开始的0位置 ms.Seek(0, SeekOrigin.Begin); ms.Read(buffer, 0, buffer.Length); return buffer; }//using }//ImageToBytes /// <summary> /// Convert Byte[] to Image /// </summary> /// <param name="bytes"></param> /// <returns></returns> public static Image BytesToImage(byte[] buffer) { MemoryStream ms = new MemoryStream(buffer); Image image = Image.FromStream(ms); return image; }//BytesToImage /// <summary> /// Convert Byte[] to a picture and Store it in file /// </summary> /// <param name="fileName"></param> /// <param name="buffer"></param> /// <returns></returns> public static string CreateImageFromBytes(string fileName, byte[] buffer) { //获取图片的格式 Image image = BytesToImage(buffer); ImageFormat format = image.RawFormat; //根据格式,设定后缀 if (format.Equals(ImageFormat.Jpeg)) { fileName += ".jpeg"; } else if (format.Equals(ImageFormat.Png)) { fileName += ".png"; } else if (format.Equals(ImageFormat.Bmp)) { fileName += ".bmp"; } else if (format.Equals(ImageFormat.Gif)) { fileName += ".gif"; } else if (format.Equals(ImageFormat.Icon)) { fileName += ".icon"; } //创建文件目录 FileInfo info = new FileInfo(fileName); Directory.CreateDirectory(info.Directory.FullName); //把数组写到指定的位置 File.WriteAllBytes(fileName, buffer); return fileName; }//CreateImageFromBytes } }
做一些介绍
Stream流类
流是 字节序列的抽象,这些字节可能来自与文件、TCP/IP套接字或内存。在.NET中,通过 Stream类适当地表示流。Stream类提供了字节序列的通用视图。
Stream类是其他所有流的基类,并且有如下的类实现:
- BufferedStream:提供另一个流上的缓冲层以改进性能
- FileStream:提供读写文件的方法
- MemoryStream:提供使用内存作为后备存储器的流
- NetworkStream:提供访问网络上的数据的方法
- CryptoStream:提供供应加密变换数据的方法
本博文中主要用到了MemoryStream,所以只对其做介绍,其他的在参考文章链接中。
有时需要在内存中操作数据,而不是采取将这些数据保存在文件中的方式,相应的示例是WindowsForm中的PictrueBox控件。例如 ,你有一张显示在PictureBox控件中的图片,并且希望将图片发送到远程服务器,例如Web Service.PictureBox控件有一个Save()方法,通过该方法可以将图像保存到Stream对象。
相比于将图像保存到FileStream对象,然后将该文件中的数据重新加载到字节数组中,更好的方法是使用MemoryStream对象,该对象使用内存作为后备存储器(相比于执行文件I/O,使用内存更为有效;文件I/O的执行速度相对缓慢)。
Image.Save方法
Image.Save 方法 (Stream, ImageFormat)
这个方法将图像以指定的格式保存到指定的流中。图像必须保存到零偏移量的流中。 如果在保存图像之前已经将任何附加数据写入到流,则流中的图像数据会损坏。
参考资料
Stream流类链接:http://blog.csdn.net/gengkunpeng/article/details/5797231