【问题标题】:Save image to disk from database with same size & quality as the original image以与原始图像相同的大小和质量将图像从数据库保存到磁盘
【发布时间】:2020-07-28 01:47:57
【问题描述】:

我正在尝试将图像保存到列类型设置为图像的 MSSQL 数据库表中,我的应用程序的目的是将用户上传的图像保存到数据库中,以后用户可以从数据库中检索这些图像并如果需要,保存到磁盘。

我已经编写了以下代码以成功完成此任务,但是当我将图像保存到从数据库中检索的磁盘时,文件大小似乎小于原始大小。

这自然意味着图像的质量在保存时降低了,或者我没有正确检索图像。

此代码用于从数据库中检索图像。

    Public Function __IMAGE_FROM_STREAM(ByVal img As Object) As Image
    __IMAGE_FROM_STREAM = Nothing
    If Not IsDBNull(img) Then
        Using mStream As New MemoryStream(img, 0, img.Length)
            mStream.Write(img, 0, img.Length)
            __IMAGE_FROM_STREAM = Image.FromStream(mStream, True)
        End Using
    End If
    Return __IMAGE_FROM_STREAM
End Function

此代码用于将传入的图像保存到数据库中。

    Public Function __IMAGE_TO_STREAM(ByVal image As Image) As Byte()
    __IMAGE_TO_STREAM = Nothing
    If Not image Is Nothing Then
        Using mStream As New MemoryStream
            Dim bm As Bitmap = New Bitmap(image)
            bm.Save(mStream, image.RawFormat)
            __IMAGE_TO_STREAM = mStream.GetBuffer
        End Using
    End If
    Return __IMAGE_TO_STREAM
End Function

此代码用于将检索到的图像保存到磁盘中。

    sfdExportImage.FileName = "export_" & DateTime.Now.ToString("d").Replace("/", "") & "_" & sender.Tag
    If sfdExportImage.ShowDialog() = DialogResult.OK Then
        Dim fileName As String = sfdExportImage.FileName
        Dim expImage As Image = flpImageContainer.Controls("flpWrap_" & sender.Tag).Controls(0).BackgroundImage
        Try
            If expImage IsNot Nothing Then
                expImage.Save(fileName)
                MessageBox.Show("File exported successfully to " & fileName, __COMPANYNAME, MessageBoxButtons.OK, MessageBoxIcon.Information)
            End If
        Catch ex As Exception
            __WRITELOG(ex)
        End Try
    End If

我已经查看了这个问题,但没有类似的问题,我是否遗漏了任何编码参数,我没有使用过很多图像及其类,因此非常感谢您的反馈。谢谢。

【问题讨论】:

  • SQL Server 中的image 数据类型已经过时了十多年,文档会告诉您应该使用varbinary 来保存任何二进制数据。
  • 我还在使用 MSSQL2008R2 会更新列类型,但这不是问题的原因吧?
  • 不,因此是评论而不是回答。

标签: .net vb.net visual-studio-2010


【解决方案1】:

该代码中有很多不可靠的东西。你的方法应该是这样的:

Public Function ImageFromDbData(data As Object) As Image
    If data Is DBNull.Value Then
        Return Nothing
    End If

    Using strm As New MemoryStream(DirectCast(data, Byte()))
        Return Image.FromStream(strm)
    End Using
End Function

Public Function ImageToDbData(img As Image) As Object
    If img Is Nothing Then
        Return DBNull.Value
    End If

    Using strm As New MemoryStream
        img.Save(strm, img.RawFormat)

        Return strm.ToArray()
    End Using
End Function

它们将直接往返于数据库值,即DBNull.ValueByte 数组。两端没有Stream,所以你的命名是错误的。当您可以只使用SaveImage 时,从Image 创建Bitmap 也没有意义。如果您想将数据库中的数据保存到文件中,那么创建 Image 对象并保存它是没有意义的。直接调用File.WriteAllBytes保存Byte数组即可。

【讨论】:

  • 那么是什么导致我的代码中图像尺寸减小。
  • 关于您对 File.WriteAllBytes 的评论,我这样做的原因是当用户希望将图像保存到磁盘时,应用程序会在图片框中显示图像,因此我只是使用图片框的 BackgroundImage 属性导出到磁盘。所以基本上图片首先来自数据库到图片框->然后用户可以点击导出到磁盘。
  • 如果你有 Byte 数组,Image 首先是从该数组创建的,那么将 Image 转换为 Byte 数组是没有意义的。如果可以,请始终使用单一的事实来源。
猜你喜欢
  • 2015-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
  • 2011-03-13
  • 1970-01-01
  • 2016-06-17
相关资源
最近更新 更多