当我尝试将一些图像加载到一个图片框中时,我遇到了内存不足的问题。
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`
答案 0 :(得分:1)
if (Image.FromFile(imageFile) != null) { Image.FromFile(imageFile).Dispose(); }
坏。您正在从文件加载图像,检查结果是否为null ...然后再次将其加载到新结果中以便您可以处置它。虽然后一部分是愚蠢的,但它没有害处。但是,第一部分是因为结果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
答案 1 :(得分:1)
图片框内部保存了您放置在其中的位图的引用。除非你摆脱了图片框,否则它会引用你加载到它的每个位图。
答案 2 :(得分:0)
你需要考虑的是,不管磁盘上存储的图片类型如何,当你打开它进行显示时,图片将变成一个位图,每个显示的像素需要4个字节。
您的代码似乎建议尝试缩略图操作。事实上,您将70个文件加载到内存中,无论显示大小如何,在内存中它们都会非常大。
例如,假设您有32位颜色深度的70个jpeg,并且说大小为1920x1080像素。你的内存要求一次性加载那么多图像是:
70 pics x 1920 pixels x 1080 pixels x 4 bytes/pixel = 580,608,000 bytes!
这是一个相当低的估计。
您可以考虑加载更少的图片或尝试使用真正的缩略图解决方案。