在做程序开发的时候,我经常会遇到一些对图片进行处理、传输、存储等方面的需求,比如说上传的图片我们应当怎么保存,用户的头像数据怎么处理等。
下面我就简单描述一下集中应用场景。
在以下实验环境中,创建的是控制台应用程序,需要安装以下包:
System.Drawing.Common
在类中需要如下引用:
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
图片的保存
图片数据可以保存到磁盘,也可以保存到数据库中。
保存到磁盘 是将图片数据直接以图片的形式保存到硬盘中,我们可以通过鼠标点击的形式查看图片数据的样子和形状,相对来说比较直观。在做 web 开发过程中,如果遇到上传图片等需求,那么需要做的是首先将图片数据流通过 http 请求的形式发送到后端,后端再将数据流处理一下保存到文件服务器指定的路径下,保存成功后再将此图片的文件服务器路径获取并保存到跟业务相关联的数据库中。这样的 好处 是图片数据不会占用我们太多的数据库资源,存取比较方便,只需要在数据库中获取图片文件服务器路径 URL 即可,而 缺点 是图片文件过大,传输并不方便,而且随着系统业务的运行时间而图片数据越来越多,在不要求图片质量有必要的情况下可以对图片进行体积压缩而后存储。
保存到数据库 的通常用到的方法是将图片数据转换成 Base64
的数据,而后存储到数据库字段中。比如说用户的个人头像,我们更希望用户头像数据跟用户的个人信息紧密关联在一起,对上传的头像图片可以转成 Base64
的数据进行存储,当获取的时候反向的将 Base64
的数据转成图片再显示即可。这样做的 优点 是图片跟业务数据关联紧密,随着数据库的查询即可将图片查询出来,再 web 应用中还可以直接使用 Base64 的数据,缺点 是 Base64 数据过长,对数据库资源的占用较大,在查询图片相关数据表时查询过程相对较为缓慢,严重影响系统性能。
读取本地图片
读取本地磁盘中的图片数据,可以直接通过 Bitmap
读取,如下所示:
Bitmap bitmap= new Bitmap(@"D:\img1.jpg");
数据格式转换
鉴于平时工作内容,通常用的最多的就是 Bitmap
和 Base64
图片数据的互转。
Bitmap 图片数据转 Byte[] 字符串: 具体详细代码如下所示:
public static Byte[] BitmapToByte(Bitmap bmp)
{
try
{
MemoryStream ms = new MemoryStream();
bmp.Save(ms, ImageFormat.Jpeg);
byte[] arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(arr, 0, (int)ms.Length);
ms.Close();
return arr;
}
catch (Exception)
{
return null;
}
}
Bitmap 图片数据转 Base64 字符串: 将 Bitmap
图片数据保存到内存中,而后从内存中读取为 byte[] 数据,将 byte[] 数据转成 Base64 字符串即可。贴上代码如下:
public static string ImgBitmapToBase64String(Bitmap bmp)
{
try
{
// 调用Bitmap 图片数据转 Byte[] 字符串的 BitmapToByte() 方法
return Convert.ToBase64String(BitmapToByte(bmp));
}
catch (Exception ex)
{
return null;
}
}
当拿到
Base64
数据后,我们就可以直接以字符串的形式保存到数据库表中了,如果是 HTML 的<img>
标签的话,可以其 Url 为"data:image/png;base64," + <base64Img>
。
Base64 字符串转 Bitmap 图片数据: 将 Base64
的图片数据转成 byte[] 保存到内存中,而后再转成 Bitmap 。贴上代码如下所示:
public static Bitmap Base64StringToImageBitmap(string strbase64)
{
try
{
byte[] arr = Convert.FromBase64String(strbase64);
MemoryStream ms = new MemoryStream(arr);
Bitmap bmp = new Bitmap(ms);
ms.Close();
return bmp;
}
catch (Exception ex)
{
return null;
}
}
保存图片到本地
将 Bitmap
图片数据保存到本地图片文件,可以采用 Bitmap
直接 Save()
的方式进行,如下所示:
bitmap.Save(@"D:\img.jpg", ImageFormat.Jpeg);