【问题标题】:Out of memory with multi images in one picturebox一个图片框中的多张图片内存不足
【发布时间】:2011-01-27 19:41:42
【问题描述】:

当我尝试将几张图片加载到一个图片框中时,我遇到了内存不足的问题。

public void button2_Click(object sender, EventArgs e)
    {


        FolderBrowserDialog dialog = new FolderBrowserDialog();
        dialog.ShowDialog();
        string selected = dialog.SelectedPath;

        string[] imageFileList = Directory.GetFiles(selected);


        int iCtr = 0,zCtr = 0;
        foreach(string imageFile in imageFileList)
        {

            if (Image.FromFile(imageFile) != null)
            {
                Image.FromFile(imageFile).Dispose();
            }

            PictureBox eachPictureBox = new PictureBox();

            eachPictureBox.Size = new Size(100,100);
           // if (iCtr % 8 == 0)
            //{
             //   zCtr++;
              //  iCtr = 0;
            //}
            eachPictureBox.Location = new Point(iCtr * 100 + 1, 1);
            eachPictureBox.Image = Image.FromFile(imageFile);
            iCtr++;

            panel1.Controls.Add(eachPictureBox);

        }


    }`enter code here`

【问题讨论】:

  • 您选择的目录中存储了多少张图片?
  • 您正在加载多张图片,但每张图片都加载到每个图片框中。那么错误代码是什么?一个尝试捕捉什么产量?可能图片太多?

标签: c# picturebox image


【解决方案1】:
if (Image.FromFile(imageFile) != null)
{
    Image.FromFile(imageFile).Dispose();
}

不好。您正在从文件中加载图像,检查结果是否为空......然后将其再次加载到新结果中,以便您可以处理它。虽然后一部分很愚蠢,但它无害。然而,第一部分是因为生成的 Image 永远不会被正确处理(如果/当 GC 收集它时,Image 类型的终结器应该处理非托管资源,但是这不是一个明智的依赖)。

顺便说一句,Image.FromFile 永远不会返回 null。如果它无法读取图像,则会抛出OutOfMemoryException

代码似乎也没有做任何事情,因为没有 else 块,并且在 if 块中没有做任何有意义的事情。

我的猜测是您的 OutOfMemoryException 是因为该目录中的一个或多个文件以损坏或不受支持的图像格式存储,或者不是位于全部。

尝试用以下代码替换 foreach 中的代码:

try
{
    Image image = Image.FromFile(imageFile);

    PictureBox eachPictureBox = new PictureBox();

    eachPictureBox.Size = new Size(100,100);

    eachPictureBox.Location = new Point(iCtr * 100 + 1, 1);
    eachPictureBox.Image = Image.FromFile(imageFile);
    iCtr++;

    panel1.Controls.Add(eachPictureBox);
}
catch(OutOfMemoryException) { } // skip the file

【讨论】:

  • 如果您的回答对您有帮助,请务必接受。
【解决方案2】:

您必须考虑的一点是,无论存储在磁盘上的图片类型如何,当您打开它进行显示时,图片都会变成位图,并且每个显示像素需要 4 个字节。

您的代码似乎建议尝试进行缩略图操作。实际上,您将 70 个文件加载到内存中,无论显示大小如何,它们在内存中都会非常大。

例如,假设您有 70 个 32 位色深的 jpeg,大小为 1920x1080 像素。您一次加载那么多图像的内存要求是:

 70 pics x 1920 pixels x 1080 pixels x 4 bytes/pixel = 580,608,000 bytes! 

这是一个相当低的估计。

您可以考虑加载更少的图片或尝试真正的缩略图解决方案。

【讨论】:

    【解决方案3】:

    图片框内部包含对您放置在其中的位图的引用。除非您摆脱图片框,否则它会引用您加载到其中的每个位图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-21
      • 1970-01-01
      • 2018-09-19
      • 2013-04-05
      相关资源
      最近更新 更多