You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

byte[]转Image失败排查:数据库图片读取转换异常

问题分析与解决方案

1. ViewBag使用错误触发空引用异常

你现在调用ViewBag.Add(ScreenshotImagesFullsize);的方式完全错了!ViewBag本质是动态的键值对集合,它的Add方法需要传入键和值,而不是直接丢一个列表进去。正确的做法是给ViewBag赋值一个命名属性,比如:

ViewBag.ScreenshotImagesFullsize = ScreenshotImagesFullsize;

原来的写法会让ViewBag无法识别你要传递的数据,直接导致"Cannot perform runtime binding on a null reference"这个错误。

2. MemoryStream提前释放导致Image失效

这是你遇到的核心问题!你在创建Image后立刻调用memstr.Dispose();,但Image.FromStream生成的Image对象不会立即把流里的图片数据复制到自身内存,它会保留对源流的引用。当你提前释放流之后,Image就失去了数据来源——这就是为什么禁用JIT优化后能看到height、width这些元数据(读取流时缓存的),但实际像素数据显示为null的原因。

两种修复方案:

方案一:让Image关联流的生命周期

直接去掉memstr.Dispose();这行代码,因为当Image对象被垃圾回收时,会自动释放关联的流。修改后的转换方法:

private List<Image> ConvertByteArraysToImages(List<byte[]> byteDataList) {
    List<Image> retVal = new List<Image>();
    int counter = 0;
    foreach (byte[] byteData in byteDataList) {
        MemoryStream memstr = new MemoryStream(byteData);
        Image img = Image.FromStream(memstr);
        retVal.Add(img);
        // 注释掉Dispose,让Image管理流的生命周期
        // memstr.Dispose();
        System.IO.File.WriteAllBytes(String.Format(@"C:\dev\test{0}.png", counter), byteData);
        counter++;
    }
    return retVal;
}

方案二:转成Bitmap复制流数据(更安全)

Bitmap对象会把流中的图片数据完整复制到自身内存,这样就可以安全释放流了,还能避免内存泄漏风险:

private List<Image> ConvertByteArraysToImages(List<byte[]> byteDataList) {
    List<Image> retVal = new List<Image>();
    int counter = 0;
    foreach (byte[] byteData in byteDataList) {
        using (MemoryStream memstr = new MemoryStream(byteData))
        {
            // 用Bitmap包装,把流数据复制到内存
            Bitmap bmp = new Bitmap(Image.FromStream(memstr));
            retVal.Add(bmp);
        } // using块结束自动释放流
        System.IO.File.WriteAllBytes(String.Format(@"C:\dev\test{0}.png", counter), byteData);
        counter++;
    }
    return retVal;
}

额外提醒:Image无法直接在视图显示

就算你解决了上面的问题,直接把Image对象传给ViewBag也没法在HTML里显示——浏览器需要的是图片URL或者Base64编码。你可以在控制器里把Image转成Base64字符串再传递:

List<string> imageBase64List = new List<string>();
foreach(var img in ScreenshotImagesFullsize)
{
    using(MemoryStream ms = new MemoryStream())
    {
        img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        byte[] imageBytes = ms.ToArray();
        string base64String = Convert.ToBase64String(imageBytes);
        imageBase64List.Add($"data:image/png;base64,{base64String}");
    }
}
ViewBag.ScreenshotBase64 = imageBase64List;

然后在视图里用<img src="@item" />就能直接显示图片了。

内容的提问来源于stack exchange,提问作者user602095

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:50:55