2014-01-31 56 views
0

* 強烈的文字 *好的,我有一個測試應用程序,它只是測試上傳和下載圖像到/從SQL Server。上傳代碼有效,但是當我嘗試從SQL Server中檢索圖像時,我收到「內存不足」錯誤。但是,當我將picturebox從.BackGroundImage更改爲.Image時,代碼完美無缺。SQL將圖片下載到圖片框'內存不足'錯誤

我所需要的圖像是在一個BackGoundImage的格式,這樣我可以很容易地改變圖像的大小(中心,舒展ECT)。

錯誤:

An unhandled exception of type 'System.OutOfMemoryException' occurred in System.Drawing.dll

Additional information: Out of memory.

用於從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 ....

這裏的上載圖像碼(WORKING)

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 [email protected] 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() 

進口和DIMS

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]

繼雅克非常有用的建議,我已經改變了我的代碼到以下 - 注意有兩個錯誤,因爲讀取未被聲明 - 應該聲明爲什麼?

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 

[EDIT 2]

我現在在retval - read.GetBytes(16, startindex ....線接收到錯誤。

An unhandled exception of type 'System.InvalidOperationException' occurred in Microsoft.VisualBasic.dll

Additional information: Invalid attempt to read when no data is present.

我迄今爲止代碼:

'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

如果您購買的'OutOfMemoryException',通常是因爲你的進程是32位的,並且已經分配了所有可尋址的2GB內存,或者它已經用完了所有的系統句柄或者GDI句柄。無論哪種方式,你都可以通過觀察任務管理器來判斷。由於System.Drawing.dll中發生錯誤,我強烈懷疑您的GDI句柄已用完。每個進程僅限於10,000個GDI對象。理想情況下,你的過程應該沒有達到那個極限。 –

回答

1

你爲什麼不使用GetBytes會從像一個DataReader(其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 
+0

我從來沒有使用GetBytes方法,並沒有線索如何實現它... – user3224987

+0

我剛剛給你一個完整的例子?你想在VB代碼中使用嗎? – Jaques

+0

是的,但我如何將它放在我的代碼中,以便它使用SQL映像並將其輸出到圖片框? – user3224987

0

我想感謝Jaques爲幫助我而付出的努力。該解決方案比答案稍簡單一些 - 這仍然導致「內存不足」錯誤。但所做的努力是非常讚賞的。最後,這段代碼沒有任何錯誤地工作。

「檢索圖片 GroupBox2.BringToFront() GroupBox2.Visible =真 Label1.Visible =假 TextBox1.Visible =假 昏暗流作爲新的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