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

首先,你的内存不足了吗?因为如果你是那么错误是有效的。

如果您没有耗尽内存,您需要做的第一件事是将代码包装在 try/catch 块中的 foreach 循环中,如下所示:

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 {}
    }
} 

原因是,正如 Jason Watkins 在评论中提到的那样,它也可能是另一种形式的错误,由于类中缺少错误消息,它只是显示为内存不足异常。

于 2013-03-23T08:15:27.703 回答