SQL将图像下载到图片框'内存不足'错误

时间:2014-01-31 11:55:40

标签: sql sql-server vb.net image sql-server-2008

* 强文 *好的,我有一个测试应用程序,它只是测试向/从SQL Server上传和下载图像。上传代码有效,但是当我尝试从SQL Server检索图像时,我收到“Out of Memory”错误。但是,当我将图片框从.BackGroundImage更改为.Image时,代码可以正常运行。

我要求图像采用BackGoundImage格式,以便我可以轻松更改图像的大小(中心,拉伸等)。

错误:

  

发生了类型为“System.OutOfMemoryException”的未处理异常   在System.Drawing.dll

中      

其他信息:内存不足。

从SQL Server检索图像的代码是:

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
'Retrieve Image
        GroupBox2.BringToFront()
        GroupBox2.Visible = True
        Label1.Visible = False
        TextBox1.Visible = False
        con.Open()
        Dim cmd As New SqlCommand("SELECT DP FROM PersonsA WHERE Members_ID = 1", con)
        cmd.CommandType = CommandType.Text
        Dim ImgStream As New IO.MemoryStream(CType(cmd.ExecuteScalar, Byte()))
        PictureBox2.BackgroundImage = Image.FromStream(ImgStream, False, True)

        ImgStream.Dispose()
        con.Close()
    End Sub

错误突出显示PictureBox2.BackgroundImage = Image.FromStream(ImgStream, False, True)行。

其他信息:

  • 预计只有1行,因为Members_ID是主键。
  • SQL Server是MS SQL Server + Management Studio。
  • DP列的格式为“图片”,并按如下方式存储图片:

0xFFD8FFE000104A46494600010201000000000000FF ...

以下是上传图片代码(工作)

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
'Upload Image
    con.Open()

    Dim cmd As New SqlCommand("UPDATE PersonsA SET DP=@DP WHERE Members_ID = 1", con)
    Dim ms As New MemoryStream()
    PictureBox1.BackgroundImage.Save(ms, PictureBox1.BackgroundImage.RawFormat)
    Dim data As Byte() = ms.GetBuffer()
    Dim p As New SqlParameter("@DP", SqlDbType.Image)
    p.Value = data
    cmd.Parameters.Add(p)
    cmd.ExecuteNonQuery()
    MessageBox.Show("Image has been saved", "Save", MessageBoxButtons.OK)
    Label1.Visible = False
    TextBox1.Visible = False

    con.Close()

导入和暗淡

Imports System.Data.SqlClient
Imports System.IO
Public Class Form1
    'path variable use for Get application running path
    Dim path As String = (Microsoft.VisualBasic.Left(Application.StartupPath, Len(Application.StartupPath) - 9))
    Dim con As New SqlConnection("CONNECTION_STRING;")
    Dim cn As New SqlConnection("CONNECTION_STRING;")
    Dim cmd As SqlCommand

为什么我收到'内存不足错误'的任何想法?该程序很小,不会使用过多的RAM,所以它必须与我的代码...

[编辑1]

根据Jaques非常有用的建议我已经将我的代码更改为以下内容 - 请注意,由于未声明读取,因此有两个错误 - 应该将其声明为什么?

 Dim cmd As New SqlCommand("SELECT DP FROM PersonsA WHERE Members_ID = 1", con)
        cmd.CommandType = CommandType.Text

        Dim Buffersize As Integer = 4096
        Dim retval As Long = 0
        Dim TempLen1 As Long = 0
        Dim startindex As Long = 0
        Dim reference_temp As [Byte]() = New [Byte](4095) {}
        Dim RefTemp As New List(Of Byte)()
        Dim Read As 
        retval = read.GetBytes(0, startindex, reference_temp, 0, buffersize)
        '0 is the first Column
        TempLen1 += retval
        While retval = buffersize
            RefTemp.AddRange(reference_temp)
            startindex += buffersize
            retval = read.GetBytes(0, startindex, reference_temp, 0, buffersize)
            TempLen1 += retval
        End While
        RefTemp.AddRange(reference_temp)
        Dim Reference_temp1 As Byte() = RefTemp.GetRange(0, CInt(TempLen1)).ToArray()
    End Sub

[编辑2]

我现在收到retval - read.GetBytes(16, startindex ....行的错误。

  

类型'System.InvalidOperationException'的未处理异常   发生在Microsoft.VisualBasic.dll

     

附加信息:没有数据时无效的读取尝试   本。

到目前为止我的代码:

  'Retrieve Image
        GroupBox2.BringToFront()
        GroupBox2.Visible = True
        Label1.Visible = False
        TextBox1.Visible = False
        con.Open()
        Dim cmd As New SqlCommand("SELECT DP FROM PersonsA WHERE Members_ID = 1", con)
        cmd.CommandType = CommandType.Text
        Dim read = cmd.ExecuteReader

        Dim Buffersize As Integer = 4096
        Dim retval As Long = 0
        Dim TempLen1 As Long = 0
        Dim startindex As Long = 0
        Dim reference_temp As [Byte]() = New [Byte](4095) {}
        Dim RefTemp As New List(Of Byte)()

        retval = read.GetBytes(16, startindex, reference_temp, 16, Buffersize)
        '0 is the first Column
        TempLen1 += retval
        While retval = buffersize
            RefTemp.AddRange(reference_temp)
            startindex += buffersize
            retval = read.GetBytes(16, startindex, reference_temp, 16, Buffersize)
            TempLen1 += retval
        End While
        RefTemp.AddRange(reference_temp)
        Dim Reference_temp1 As Byte() = RefTemp.GetRange(16, CInt(TempLen1)).ToArray()

        Dim ImgStream As New IO.MemoryStream(Reference_temp1)
        PictureBox2.BackgroundImage = Image.FromStream(ImgStream, False, True)
        ImgStream.Dispose()

2 个答案:

答案 0 :(得分:1)

为什么不使用DataReader中的GetBytes(它的C#,但我相信你可以转换它:))

'Retrieve Image
        GroupBox2.BringToFront()
        GroupBox2.Visible = True
        Label1.Visible = False
        TextBox1.Visible = False
        con.Open()
        Dim cmd As New SqlCommand("SELECT DP FROM PersonsA WHERE Members_ID = 1", con)
        cmd.CommandType = CommandType.Text
        Dim read = cmd.ExecuteReader();
        if(read.HadRows) then       
             read.Read()   'Reads the first record from the DataReader

将其转换为VB:

int buffersize = 4096;
long retval = 0;
long TempLen1 = 0;
long startindex = 0;
Byte[] reference_temp = new Byte[4096];
List<byte> RefTemp = new List<byte>();
retval = read.GetBytes(0, startindex, reference_temp, 0, buffersize);   //0 is the first Column
TempLen1 += retval;
while (retval == buffersize)
{
    RefTemp.AddRange(reference_temp);
    startindex += buffersize;
    retval = read.GetBytes(0, startindex, reference_temp, 0, buffersize);
    TempLen1 += retval;
}
RefTemp.AddRange(reference_temp);
byte[] Reference_temp1 = RefTemp.GetRange(0, (int)TempLen1).ToArray();

然后添加您的代码

Dim ImgStream As New IO.MemoryStream(Reference_temp1)
PictureBox2.BackgroundImage = Image.FromStream(ImgStream, False, True)
ImgStream.Dispose()
EndIf

答案 1 :(得分:0)

我要感谢Jaques帮助我的努力。解决方案比答案简单得多 - 这仍然导致了“内存不足”问题。错误。但所做的努力非常受欢迎。最后,这段代码没有任何错误。

&#39;检索图片         GroupBox2.BringToFront()         GroupBox2.Visible = True         Label1.Visible = False         TextBox1.Visible = False         Dim stream As New MemoryStream()

    con.Open()

    Dim cmd As New SqlCommand("SELECT DP FROM PersonsA WHERE Members_ID = 1", con)
    cmd.CommandType = CommandType.Text

    Dim image As Byte() = DirectCast(cmd.ExecuteScalar(), Byte())
    Stream.Write(image, 0, image.Length)

    con.Close()

    Dim bitmap As New Bitmap(stream)
    PictureBox2.BackgroundImage = bitmap
    PictureBox2.BackgroundImageLayout = ImageLayout.Stretch