image.fromstream 参数无效原因分析及解决

4 篇文章 0 订阅

1.问题

最近由于后端接口更改,请求验证码会抛异常,具体就是 image.fromstream(stream)函数里,

using (var streamSub = new MemoryStream(imageStream))
{
    pictureBox_Captcha.Image = Image.FromStream(streamSub);
}

经调试,构造stream对象的字节流如下,

"data:image/png;base64,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"

然后采取了如下操作,

直接将该字节流粘贴到浏览器地址栏(注意去掉开头和结尾的引号"")回车,会打开显示该字节流对应的图片,如下,

搜索base64图片在线转换,如http://tool.chinaz.com/tools/imgtobase/,将字节流粘贴到base64位置,点击转为图片,依旧没问题~

这就奇怪了,为什么 image.fromstream(stream)会抛异常?鼠标放到代码上按F1键弹出官方文档Image.FromStream Method,也没看出个所以然来,这该如何是好;

2.解决思路

其实上述已经在尝试解决了,验证数据有没有错误,看官方文档关于Image.FromStream Method的描述,然而还是没发现问题,那么该怎么办?请跟随博主继续探索,

  • 得到字节流后,粘贴到浏览器中(见上文)回车,将展示的图片邮件保存到本地,这样就是同样的图片;
  • 然后使用如下代码测试,
using (var streamTest = new MemoryStream(pictureBytes))
{
    string testPath = @"C:\test\下载.png";
    Image testImage = Image.FromFile(testPath);

    testImage.Save(streamTest, System.Drawing.Imaging.ImageFormat.Png);
    var TestArray = streamTest.ToArray();
    string strTest2 = Convert.ToBase64String(TestArray);
    string strTest = System.Text.Encoding.UTF8.GetString(TestArray);

    //  this is valid.
    var imageT1 = Image.FromStream(streamTest);

    //  this is valid too.
    Test(TestArray);

    //  as before showes, this is also valid.
    Test(Convert.FromBase64String(strTest2));
}
private void Test(byte[] value)
{
    using (var streamSub = new MemoryStream(value))
    {
        Image image = Image.FromStream(streamSub);
    }
}
  • 其中将字节流序列化到图片,再反序列化到内存中,用Convert.ToBase64String()转为strTest2如下,
"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j/NjxlKGJRvcNS6gMvfKcvpPoOPwnyS7PQtJ754wB1yYv7xGJbEbTguA1EOnlLIOp/UnOxnsRFeWoOItuENPiXRvcbHSEe+B14DelTU1FFrMoiYUbAEA1oqODjy/+otiMRf8E4p9ZITs4ELoxK2DXsZ3BvUSLjUYcPN4VhYmr/MCC6ZY+GU9T99VbRyEiA57WDlNvayLOhyt9ubnOlOcoT7Si4K1ke9EI859CC9bNGDonbzee889rwkHeHiZTiXNlP6B+u6gkSFkaXWY0m3eTGlPqw5cAuk/U75kQIFsEUOsErtP/aF9rcnq1jc8wlYevFGIst9H7EfJzwjG/frnqENGf4T3zb97vCIiBm7dYn6wycCCvgyF5ILoV7oDXuHs7nmk/9w9z63/FKd9C7XszY92NZe71RfsJ0ja+mCbdP5Z3XSu6skU9YJM3TZZM0Acd/J6h0XGL5HIqS/g5Uit7x2ThAUdWXuQah+6GIZ4M8hE+vSLZFJdcXScRHrctwo0AAKB/xv6IYMALD9g/Queza78c1QeGQAAAABJRU5ErkJggjVVVndmYks3eGhlT2Z3cXFFNGhmajZOamNYNmxZNll3c0c4VDV4d3UxZlM0VGhNWTdPemNSQjdEelBqSjVNR2Jac1VOZllJTXBjd3hyVG4wREhwajlKZGtkV2t1emlsNEFLbXltdVVYN00xa3NzSVBYUVJZbFFheHp2R094Q1dXdFF5UzdQaFhSZlNZbkVsdStCMTRCS05XWE9zaThvV1hzN1lLM1Nhdkdwc1RnR2o4R25ZTmFSRWZMYWE4SGVTd2VWa0RtVzFFdnA0NnV5b3c2dnlzS2t6UjZtZ0NVV2VsUEZVSFhYNmdZaG8vZWFyVG5OZlpUclNweXRqdWJuanBVNFEvMmtGb1huRXgxRUk4TlRmcUlCUVQvRzY1MTNYUE9hemZlc0xvbURLUDBOOWQ5REkwUEkxR1lUcFhzOWlkTGVOaVdvQkZKL0puL3BuTzhyMkJoaURZOXc5enhxdmRtbGJuaVlLamwxcHhCbHY0dW84OG5IQXVGZTlEblNDcWYvOFcrY1Yxall3TjkvMzA5WXBCNHBKRGZFR1pVN29CWFNEeThqOWVmaFpTNzFKeS8xRytpbDdwemYzVkxwZXNVaHhHL3ZqK2JkVzU2dVhFQ1hQcDRzVzVHaDNDdHNVVHNsOVpsL0tTVjVjYm5qdk5UcSt3bUwvR3pXaTZUSDBQVVF4RmhJRnRLWG5pZUw2cXBmcGlpa2ZjMzMzeDBmckFmWC9nRjI4OWJoTnlXalhnQUFBQUJKUlU1RXJrSmdnZz09In0="

和原字节流对比,看出什么了没?少了开头的子字符串:"data:image/png;base64,",并且后续的子字符串也不完全一样,如果在strTest2前加上"data:image/png;base64,",然后放到浏览器或者在线转图片转出来的图片效果和上面的完全一样,

而上述代码中的

string strTest2 = Convert.ToBase64String(TestArray);
string strTest = System.Text.Encoding.UTF8.GetString(TestArray);

两语句同样是调用Image.FromStream()为什么就没问题了呢?

因为这两句都是仅图片对应的base64字符串转为二进制字节流(原始字节流,非base64)后再调用Image.FromStream()接口的,

到这里就基本发现问题了,应该将获取到的字节流(包含已base64编码后的图片字节流)中的base64图片字节流提取出来,再还原为原始的字节流后调用接口,

byte[] imageStream = Convert.FromBase64String(GetImageBase64(capData.captchaImage));
using (var streamSub = new MemoryStream(imageStream))
{
    picBox.Image = Image.FromStream(streamSub);
}
private string GetImageBase64(string strContent)
{
    string[] strSubs = strContent.Split(':', ';', ',');
    return strSubs[strSubs.Length - 1];
}

问题解决~

3.总结

经初步验证问题后,不一定会定位到具体问题所在,如果没有定位到,不妨创建一种肯定不会出错的场景(比如本文中,由原始图片文件反序列化到字节流,再调用接口转为image对象),得到没有问题的场景下的数据,然后与此前有问题的数据进行对比,这样更直观、准确和容易的分析出问题原因,然后去解决。

递推,归纳法亦是如此。

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值