问题背景:
在C#下使用Convert.ToBase64String()将Picture控件中Image转换成Base64字符串,再使用Convert.FromBase64String()将Base64字符串转成Picture控件中Image,这个没问题。但在Vue前端使用“‘data:image/png;base64,’+Base64字符串”这个形式加载图片时却无法显示图片。
问题分析:
将同一张图片使用第三方Base64转码工具编码,发现生成的编码内容和长度与C#完全不同,但该码用在Vue前端却能正常显示出图片。
上网查原因,问题集中在Java与C#的Byte类型定义不同上,有人建议在C#使用Convert.ToBase64String()前将Byte类型转为sByte类型,但结果一样,原因是最后使用Convert.ToBase64String()时C#将sByte类型自动转换成Byte类型。
分析Base64编码原理,使用C#和Java分别对同一对象编码,发现结果完全一样,问题不在开发语言上。
问题可能出现在源头上,即图片转成的字节流是否一致?
问题发现:
使用同一张图片分两个场景做测试:一个场景是当前场景,先将图片文件导入Picture控件,再使用控件中Image属性作为字节流来源,得出Base64字符串;另一场景是将图片文件直接作为字节流来源。结果发现两者结果不一样,后者得到的编码与第三方Base64转码工具完全一致,也即从Picture控件导出的图片字节流与直接从图片文件读取的字节流不是一样的,问题就出在编码前的字节流上。
进一步的分析发现,图片文件经转Image后再Base64编码和由图片文件直接Base64编码是不一样的,理由其实很简单,虽然都能显示为图片,但Image和文件本身就不是同一种类型。
/// <summary>
/// 图片Image转Base64
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
public static string imgTob64(Image img)
{
BinaryFormatter binFormatter = new BinaryFormatter();
MemoryStream memStream = new MemoryStream();
binFormatter.Serialize(memStream, img);
byte[] bytes = memStream.GetBuffer();
string base64 = Convert.ToBase64String(bytes);
return base64;
}
/// <summary>
/// 图片文件转Base64
/// </summary>
/// <param name="imagePath">图片文件路径</param>
/// <returns></returns>
public static string imgTob64(string imagePath)
{
FileStream files = new FileStream(imagePath, FileMode.Open);
byte[] imgByte = new byte[files.Length];
files.Read(imgByte, 0, imgByte.Length);
files.Close();
string base64 = Convert.ToBase64String(imgByte);
return base64;
}
解决方法:
直接使用图片文件作为Base64编码字节流来源,问题解决。
总结:
平时有问题我都是从网上找到解决办法的,省时高效,深知知识分享的重要性。本次问题从出现到解决,我花了近两天时间,如此耗时是因为我在网上确没找到真正的原因和解决办法。为帮助有类似问题的同行不再像我这样耗费时间,故在此做一次技术分享。