C#编程中的Image/Bitmap与base64的转换及 Base-64 字符数组或字符串的长度无效问题 解决

时间:2022-09-27 14:29:33

最近用base64编码传图片遇到了点问题,总结下。

首先总结下base64编码的逻辑,来自网络:https://www.cnblogs.com/zhangchengye/p/5432276.html

Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码。它将需要编码的数据拆分成字节

数组。以3个字节为一组。按顺序排列24 位数据,再把这24位数据分成4组,即每组6位。再在每组的的最高位前

补两个0凑足一个字节。这样就把一个3字节为一组的数据重新编码成了4个字节。当所要编码的数据的字节数不是

3的整倍数,也就是说在分组时最后一组不够3个字节。这时在最后一组填充1到2个0字节。并在最后编码完成后在

结尾添加1到2个 “=”。

例:将对ABC进行BASE64编码:

1、首先取ABC对应的ASCII码值。A(65)B(66)C(67);
2、再取二进制值A(01000001)B(01000010)C(01000011);
 3、然后把这三个字节的二进制码接起来(010000010100001001000011);
4、 再以6位为单位分成4个数据块,并在最高位填充两个0后形成4个字节的编码后的值,(00010000)(00010100

)(00001001)(00000011),其中蓝色部分为真实数据;
 5、再把这四个字节数据转化成10进制数得(16)(20)(9)(3);
 6、最后根据BASE64给出的64个基本字符表,查出对应的ASCII码字符(Q)(U)(J)(D),这里的值实际就是

数据在字符表中的索引。

注:BASE64字符表:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

Image或bitmap与base64互转的办法:(网上很多了,仅供参考)

public static Bitmap GetImageFromBase64(string base64string)
{
byte[] b = Convert.FromBase64String(base64string);
MemoryStream ms = new MemoryStream(b);
Bitmap bitmap = new Bitmap(ms);
return bitmap;
} public static string GetBase64FromImage(Image imagefile)
{
try
{
//Bitmap bmp = new Bitmap(imagefile); //MemoryStream ms = new MemoryStream();
//bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); //byte[] arr = new byte[ms.Length];
//ms.Position = 0;
//// ms.Seek(0, SeekOrigin.Begin);
//ms.Read(arr, 0, (int)ms.Length);
//ms.Close();
//return Convert.ToBase64String(arr);
using (MemoryStream ms = new MemoryStream())
{
imagefile.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Seek(0, SeekOrigin.Begin);
// byte[] arr = ms.GetBuffer();
byte[] arr = ms.ToArray(); return Convert.ToBase64String(arr);
}
}
catch (Exception)
{
return "";
}
}

  

下面说说遇到的问题:

C#编程中的Image/Bitmap与base64的转换及  Base-64 字符数组或字符串的长度无效问题   解决

Convert.FromBase64String(base64string);时偶尔报错

“System.FormatException”类型的未经处理的异常在 mscorlib.dll 中发生

其他信息: Base-64 字符数组或字符串的长度无效。

众所周知这种转换超级简单,实在想象不出是什么原因。

由上面的编码方式可知,base64编码后长度必须是4的倍数,不足则用=补齐

而根据对方接收的,确实不是4的倍数,而我这边记录的是4的倍数。

后来查看解析方代码知道原因了:

他收到xml后先替换utf8成GBK,这样如果正好base64字符串里含有utf8就会被替换,替换后就不是4的倍数就报错了。

strXml = strXml.Replace("UTF-8", "GBK").Replace("utf8", "GBK");

很简单的错误,查了很久。

这类错误,一般查询是否什么特殊字符被替换就行了,比如url传参之类的。不要考虑转换过程可能有问题,基本不存在的。