0

リストに約60枚の写真をロードしようとしています。各画像は約1MBです。20枚の写真では問題ありませんが、それを超えると、以下のコード行でメモリ不足の例外が発生します。キーワードとストリームの「使用」について言及しているものもありましたが、私は初心者なので、誰か助けてください。

Image image = Bitmap.FromFile(Filename);

これが私のコードです

  private void LoadBtn_Click_1(object sender, EventArgs e)
    {
        OpenFileDialog newDialog = new OpenFileDialog();
        if (newDialog.ShowDialog() == DialogResult.OK)
        {
            images.Clear();

            string dirPath  = System.IO.Path.GetDirectoryName(newDialog.FileName.ToLower()); 
            DirectoryInfo di = new DirectoryInfo(dirPath);
            FileInfo[] finfos = di.GetFiles("*.*");

            foreach (FileInfo fi in finfos)
            {
                string ext = fi.Extension.ToLower();
                if ((ext.Equals(".png")) || (ext.Equals(".jpg")) || (ext.Equals(".tif")) ||                  (ext.Equals(".gif")))
                {
                    string Filename = fi.FullName;
                    Image image = Bitmap.FromFile(Filename); //exception occurs HERE
                    images.Add(image);
                    //this.imageList1.Images.Add(image);
                    //image.Dispose();
                }
            } 
        }

        pictureBox3.Image = images[0];

    }

私はC#、Windowsフォームを使用しています。ありがとう

4

2 に答える 2

1

あなたが言及したソフトウェアを見た後、私が言ったように、サムネイルだけが必要な場合は、画像全体をメモリにロードする必要はありません。

だから私はクラスを作成します

class ImageAndThumb
{
    public Image Thumb;
    public Image Big;
    private string ImagePath;
    public ImageAndThumb(string fileName)
    {         
        ImagePath = fileName;
        Image image = Image.FromFile(fileName)
        Image thumb = img.GetThumbnailImage(200, 200, ()=>false, IntPtr.Zero);
    }
    public Image LoadBigImage()
    {
        Big = Image.FromFile(ImagePath);
        return Big;
    }
    public void UnloadImage()
    {
        Big = null;
    }

}

次に、そのクラスを使用します。

List<ImageAndThumb> Images = new List<ImageAndThumb>();
  private void LoadBtn_Click_1(object sender, EventArgs e)
    {
        OpenFileDialog newDialog = new OpenFileDialog();
        if (newDialog.ShowDialog() == DialogResult.OK)
        {
            Images.Clear();

            string dirPath  = System.IO.Path.GetDirectoryName(newDialog.FileName.ToLower()); 
            DirectoryInfo di = new DirectoryInfo(dirPath);
            FileInfo[] finfos = di.GetFiles("*.*");

            foreach (FileInfo fi in finfos)
            {
                string ext = fi.Extension.ToLower();
                if ((ext.Equals(".png")) || (ext.Equals(".jpg")) || (ext.Equals(".tif")) ||                  (ext.Equals(".gif")))
                {
                    string Filename = fi.FullName;
                    ImageAndThumb image = new ImageAndThumb(Filename); 
                    Images.Add(image);
                }
            } 
        }

        pictureBox3.Image = Images[0].Thumb; // << Much less memory usage;

    }

そして今、画像を使用する必要があるときはいつでも、最初にそれをロードします。例:

void ShowPicture(int index)
{
    Images[index].LoadBigImage();
    PictureBoxBig.image = Images[index].Big;
}
void ClosePicture(int index)
{
    Images[index].UnloadImage();
}

別のイメージをロードしたら、イメージをアンロードすることをお勧めします。

int currentPictureIndex = -1;
    void ShowPicture(int index)
    {
        Images[index].LoadBigImage();
        PictureBoxBig.image = Images[index].Big;
        if(CurrentPictureIndex > -1) ClosePicture(CurrentPictureIndex);
        currentPictureIndex = index;
    }
于 2013-03-23T08:10:57.287 に答える
0

まず、メモリ不足ですか?あなたがそうなら、エラーは有効です。

メモリが不足していない場合、最初に行う必要があるのは、次のように foreach ループのコードを try/catch ブロックでラップすることです。

foreach (FileInfo fi in finfos)
{
    string ext = fi.Extension.ToLower();
    if ((ext.Equals(".png")) || (ext.Equals(".jpg")) || (ext.Equals(".tif")) || (ext.Equals(".gif")))
    {
        try 
        {
            string Filename = fi.FullName;
            Image image = Bitmap.FromFile(Filename); //exception occurs HERE
            images.Add(image);
            //this.imageList1.Images.Add(image);
            //image.Dispose();
        }
        catch {}
    }
} 

その理由は、ジェイソン・ワトキンスがコメントで述べたように、クラスにエラーメッセージがないためにメモリ不足の例外として表示される別の形式のエラーである可能性があるためです。

于 2013-03-23T08:15:27.703 に答える