* 强文 *好的,我有一个测试应用程序,它只是测试向/从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)
行。
其他信息:
Members_ID
是主键。 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()
答案 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