VB.NET从.SQL还原的MySQL库取Image调用Save报空引用错误
VB.NET 调用Image.Save抛出空引用异常排查记录
问题背景
- 运行环境:Windows 10 Pro 系统,Visual Studio 2017,VB.NET 开发,连接的 MySQL 数据库由 .SQL 备份文件还原得到。
- 故障表现:此前运行正常的图片读取、保存逻辑,执行到
MyOnlineImg.Save代码行时抛出 未将对象引用设置到对象的实例(Object reference not set to an instance of an object) 错误,初步调试未定位到异常点。
原始实现代码
Dim MyOnlineImg As System.Drawing.Image MyOnlineImg = GetImagefromDB(ImgID, Now) Dim ms As New MemoryStream() Dim myImageCodecInfo As ImageCodecInfo Dim myEncoder As System.Drawing.Imaging.Encoder Dim myEncoderParameter As EncoderParameter Dim myEncoderParameters As EncoderParameters myImageCodecInfo = GetEncoderInfo(ImageFormat.Png) myEncoderParameters = New EncoderParameters(1) myEncoder = System.Drawing.Imaging.Encoder.Quality myEncoderParameter = New EncoderParameter(myEncoder, CType(50L, Int32)) myEncoderParameters.Param(0) = myEncoderParameter MyOnlineImg.Save(ms, myImageCodecInfo, myEncoderParameters)
已做排查操作
- 调整代码写法后报错未消失,调试时观察到以下对象已正常实例化:
ms = {System.IO.MemoryStream} pngCodec = {System.Drawing.Imaging.ImageCodecInfo} myEncoderParameters = {System.Drawing.Imaging.EncoderParameters}
调整后的代码如下:
Dim ms As New MemoryStream() Dim myImageCodecInfo As ImageCodecInfo Dim myEncoder As System.Drawing.Imaging.Encoder myImageCodecInfo = GetEncoderInfo(ImageFormat.Png) myEncoder = System.Drawing.Imaging.Encoder.Quality Dim pngCodec As ImageCodecInfo = GetEncoderInfo(ImageFormat.Png) Dim myEncoderParameters As New EncoderParameters() myEncoderParameters.Param(0) = New EncoderParameter(Encoder.Quality, 50) Dim MyOnlineImg As System.Drawing.Image = GetImagefromDB(ImgID, Now) MyOnlineImg.Save(ms, pngCodec, myEncoderParameters)
- 增加空值判断断点,确认
MemoryStream流对象、pngCodec图像编码信息对象、myEncoderParameters编码参数对象均不为空,空值判断代码如下:
If ms Is Nothing Then Dim blah As String = "" End If If pngCodec Is Nothing Then Dim blah As String = "" End If If myEncoderParameters Is Nothing Then Dim blah As String = "" End If
根因定位
排查逻辑存在两个遗漏点:
- 未校验核心对象
MyOnlineImg的有效性:数据库从备份文件还原时,可能出现部分图片字段二进制数据截断、丢失、损坏的情况,会导致GetImagefromDB方法返回Nothing,此时直接调用.Save()方法会直接触发空引用错误。 - 编码器参数使用错误:PNG 为无损压缩格式,原生不支持
Encoder.Quality质量参数,即使MyOnlineImg对象正常实例化,给 PNG 编码器传入不支持的质量参数,也会触发 GDI+ 内部的空引用异常。
修复方案
' 第一步:校验从数据库读取的图片对象是否有效 Dim MyOnlineImg As System.Drawing.Image = GetImagefromDB(ImgID, Now) If MyOnlineImg Is Nothing Then ' 此处添加损坏数据处理逻辑:比如记录损坏的图片ID、加载默认占位图等 Throw New Exception($"ID为{ImgID}的图片数据损坏,无法正常读取") End If Using ms As New MemoryStream() ' 按图片格式选择对应保存逻辑,PNG不支持质量参数,仅JPG等有损格式支持 If ImageFormat.Png.Equals(MyOnlineImg.RawFormat) Then MyOnlineImg.Save(ms, ImageFormat.Png) Else Dim jpgCodec As ImageCodecInfo = GetEncoderInfo(ImageFormat.Jpeg) Dim encoderParams As New EncoderParameters(1) encoderParams.Param(0) = New EncoderParameter(Encoder.Quality, 50L) MyOnlineImg.Save(ms, jpgCodec, encoderParams) End If ' 此处添加内存流后续处理逻辑 End Using
验证步骤
- 在
Save方法调用前加断点,检查MyOnlineImg是否为Nothing,同时核对数据库中对应图片字段的二进制长度是否与备份前一致,排除备份还原导致的数据损坏问题。 - 如果图片对象正常,移除 PNG 格式对应的 Quality 编码参数即可解决报错,质量参数仅对 JPEG 等有损压缩格式生效。
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

