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

从数据库检索图片时画质变差且背景变黑的问题求助

问题解决方法

问题根源

  1. 背景变黑:你的原图是带透明通道的PNG格式,但保存时强制转成了JPEG——JPEG不支持透明,透明区域会被自动填充为黑色。
  2. 画质下降:直接调用Image.Save保存JPEG时用了默认压缩参数,压缩率过高导致画质严重损失。
  3. 数据冗余异常:用MemoryStream.GetBuffer()获取字节数组,它返回的是内存流的整个缓冲区(包含未使用的空字节),可能导致读取时解析异常。

修正方案

方案1:保留透明背景(存为PNG格式)

修改保存代码,以PNG格式存入数据库,完整保留透明通道:

Dim mstream As New System.IO.MemoryStream()
Try
    ' 保存为PNG格式,保留透明属性
    PictureBox1.Image.Save(mstream, System.Drawing.Imaging.ImageFormat.Png)
Catch ex As Exception
    MessageBox.Show("图片保存失败:" & ex.Message)
    Return
End Try

' 使用ToArray()获取实际有效字节数据,避免冗余空字节
Dim arrimage() As Byte = mstream.ToArray()
mstream.Close()

CMD = New SqlCommand("Update setting_TBL set Image_Value=@p1 Where Setting_name=@p2", sqlcon)
CMD.Parameters.AddWithValue("@p1", arrimage)
CMD.Parameters.AddWithValue("@p2", "Company_Logo")
CMD.ExecuteNonQuery() ' 别忘了执行更新命令

方案2:必须用JPEG格式(处理透明+提高画质)

如果业务要求必须存JPEG,需要先替换透明背景为白色(或指定颜色),同时设置高质量压缩参数:

Dim mstream As New System.IO.MemoryStream()
Try
    ' 创建带白色背景的画布,覆盖原图透明区域
    Dim bmp As New Bitmap(PictureBox1.Image.Width, PictureBox1.Image.Height)
    Using g As Graphics = Graphics.FromImage(bmp)
        g.Clear(Color.White)
        g.DrawImage(PictureBox1.Image, 0, 0)
    End Using

    ' 设置JPEG高质量保存参数(质量值0-100,越高画质越好)
    Dim jpegParams As New System.Drawing.Imaging.EncoderParameters(1)
    jpegParams.Param(0) = New System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L)
    Dim jpegCodec As ImageCodecInfo = GetEncoder(ImageFormat.Jpeg)
    
    ' 保存高质量JPEG
    bmp.Save(mstream, jpegCodec, jpegParams)
    bmp.Dispose()
Catch ex As Exception
    MessageBox.Show("图片保存失败:" & ex.Message)
    Return
End Try

Dim arrimage() As Byte = mstream.ToArray()
mstream.Close()

CMD = New SqlCommand("Update setting_TBL set Image_Value=@p1 Where Setting_name=@p2", sqlcon)
CMD.Parameters.AddWithValue("@p1", arrimage)
CMD.Parameters.AddWithValue("@p2", "Company_Logo")
CMD.ExecuteNonQuery()

需要补充辅助函数获取JPEG编码器:

Private Function GetEncoder(format As ImageFormat) As ImageCodecInfo
    Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageDecoders()
    For Each codec As ImageCodecInfo In codecs
        If codec.FormatID = format.Guid Then
            Return codec
        End If
    Next
    Return Nothing
End Function

检索代码优化

检索时不要提前关闭MemoryStream,Image.FromStream需要流保持打开状态:

Dim Da As New SqlDataAdapter
Dim DT As New DataTable

Da = New SqlDataAdapter("Select Image_Value From Setting_Tbl Where Setting_Name='Company_Logo'", sqlcon)
Da.Fill(DT)

If DT.Rows.Count > 0 Then
    Dim picbyte() As Byte = DT.Rows(0).Item("Image_Value")
    Dim pic As New System.IO.MemoryStream(picbyte)
    PictureBox1.Image = Image.FromStream(pic)
    PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End If

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:13:26