3

次のコードを使用して、画像をサムネイルとしてFlowLayoutPanelコントロールにロードしています。残念ながら私はOutOfMemory例外が発生します。画像のロード中にメモリ不足の例外が発生しました

すでにメモリリークがライン

Pedit.Image = System.Drawing.Image.FromStream(fs) 

で発見され、どのように私は次のコードを最適化することができると思い通り?

Private Sub LoadImagesCommon(ByVal FlowPanel As FlowLayoutPanel, ByVal fi As FileInfo) 
     Pedit = New DevExpress.XtraEditors.PictureEdit 
     Pedit.Width = txtIconsWidth.EditValue 
     Pedit.Height = Pedit.Width/(4/3) 
     Dim fs As System.IO.FileStream 
     fs = New System.IO.FileStream(fi.FullName, IO.FileMode.Open, IO.FileAccess.Read) 
     Pedit.Image = System.Drawing.Image.FromStream(fs) 
     fs.Close() 
     fs.Dispose() 
     Pedit.Properties.SizeMode = DevExpress.XtraEditors.Controls.PictureSizeMode.Zoom 

     If FlowPanel Is flowR Then 
      AddHandler Pedit.MouseClick, AddressOf Pedit_MouseClick 
      AddHandler Pedit.MouseEnter, AddressOf Pedit_MouseEnter 
      AddHandler Pedit.MouseLeave, AddressOf Pedit_MouseLeave 
     End If 

     FlowPanel.Controls.Add(Pedit) 
    End Sub 

更新:画像の数のロード中に問題が発生した(300dpiので3264x2448pxを - 各画像は3Mbの者についてです)(あなたのFromStreamに関連している)Image.FromFileため

+0

は、すべての余分なコードを削除し、画像をロードするためにだけ試みることによって、問題を特定しようとしたことがありますか?読み込まれたイメージを(それが遠くにある場合)「通常の」イメージ表示コントロールに割り当ててみましたか? –

+1

イメージを1つだけ読み込んだり、多くのイメージを読み込んだりすると、メモリが不足していませんか?画像を読み込もうとすると、問題を引き起こす画像は1つだけですか、失敗しますか?イメージは非常に大きいですか?もっと詳しく、または私たちができることは最高だと思います。 –

+0

@ Jim。こんにちは、更新を確認してください。 – OrElse

答えて

3

あなたはいくつかの手順でこの問題を解決することができます。ファイル依存性から無料で入手する

  • 、あなたは画像をコピーする必要があります。実際にそれを新しいビットマップに描画するだけで、それをコピーすることはできません。
  • サムネイルが必要なため、ソースビットマップがかなり大きいので、これを組み合わせてイメージを縮小します。
+0

をロードしていたテキストファイルを持っていました...そして、私は3番目の関連する質問を投稿する準備ができました...どのように "ACDSee"タイプのプログラムがこれを管理していますか? – OrElse

+0

@chocol:ACDseeなどは、サムネイルを作成して、残りの部分に負荷の要求を使用すると思います。 –

5

ドキュメントは、それがすると言っていますファイルが有効なイメージ形式でない場合、またはGDI +がピクセル形式をサポートしていない場合はOutOfMemoryExceptionをスローします。サポートされていないイメージタイプをロードしようとしている可能性はありますか?

また、Image.FromStreamのドキュメントでは、イメージのライフタイムの間ストリームを開いたままにしておく必要があると言われています。そのため、コードがイメージを読み込んだとしても、まだアクティブです。 http://msdn.microsoft.com/en-us/library/93z9ee4x.aspxを参照してください。思考の

+0

+1 - 私は – blak3r

3

カップル:ジムが述べたように、MSDNのページに発言として

まず第一に、Image.FromStreamストリームを使用する場合は、画像の寿命のために開いたままにしてください。そのため、ファイルの内容をMemoryStreamにコピーし、後者を使用してImageインスタンスを作成することをお勧めします。したがって、ファイルハンドルをできるだけ解放することができます。

第2に、使用している画像がかなり大きい(圧縮されていない、メモリに存在するので、幅x高さx BytesPerPixel)。使用しているコンテキストが小さい場合は、サイズを変更し、後で使用するためにサイズ変更されたバージョンをどこかにキャッシュすることを検討してください。

最後に、不要になった画像とストリームを廃棄することを忘れないでください。

0

私は同じ問題を抱えていました。ジム・ミッシェルの答えは、無実の.txtファイルのロードが原因であることを発見しました。誰かが興味がある場合のために私の方法です。ここで

は私の方法です:

/// <summary> 
/// Loads every image from the folder specified as param. 
/// </summary> 
/// <param name="pDirectory">Path to the directory from which you want to load images. 
/// NOTE: this method will throws exceptions if the argument causes 
/// <code>Directory.GetFiles(path)</code> to throw an exception.</param> 
/// <returns>An ImageList, if no files are found, it'll be empty (not null).</returns> 
public static ImageList InitImageListFromDirectory(string pDirectory) 
{ 
    ImageList imageList = new ImageList(); 

    foreach (string f in System.IO.Directory.GetFiles(pDirectory)) 
    { 
     try 
     { 
      Image img = Image.FromFile(f); 
      imageList.Images.Add(img); 
     } 
     catch 
     { 
      // Out of Memory Exceptions are thrown in Image.FromFile if you pass in a non-image file. 
     } 
    } 

    return imageList; 
} 
関連する問題