6 .net c# io image out-of-memory
这是我的Picture.cs类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
namespace SharpLibrary_MediaManager
{
public class Picture:BaseFile
{
public int Height { get; set; }
public int Width { get; set; }
public Image Thumbnail { get; set; }
/// <summary>
/// Sets file information of an image from a given image in the file path.
/// </summary>
/// <param name="filePath">File path of the image.</param>
public override void getFileInformation(string filePath)
{
FileInfo fileInformation = new FileInfo(filePath);
if (fileInformation.Exists)
{
Name = fileInformation.Name;
FileType = fileInformation.Extension;
Size = fileInformation.Length;
CreationDate = fileInformation.CreationTime;
ModificationDate = fileInformation.LastWriteTime;
Height = calculatePictureHeight(filePath);
Width = calculatePictureWidth(filePath);
}
}
public override void getThumbnail(string filePath)
{
Image image = Image.FromFile(filePath);
Thumbnail = image.GetThumbnailImage(40, 40, null, new IntPtr());
}
private int calculatePictureHeight(string filePath)
{
var image = Image.FromFile(filePath);
return image.Height;
}
private int calculatePictureWidth(string filePath)
{
var image = Image.FromFile(filePath);
return image.Width;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我正在使用该类从给定文件夹中的每个文件中提取信息:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace SharpLibrary_MediaManager
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string folderPath = @"D:\Images\PictureFolder";
private void button1_Click(object sender, EventArgs e)
{
DirectoryInfo folder = new DirectoryInfo(folderPath);
List<Picture> lol = new List<Picture>();
foreach (FileInfo x in folder.GetFiles())
{
Picture picture = new Picture();
picture.getFileInformation(x.FullName);
lol.Add(picture);
}
MessageBox.Show(lol[0].Name);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我得到了Out Of Memory异常,我真的不知道为什么.这是我第一次做这样的事情所以我对批处理文件处理等很陌生.
有帮助吗?:)
编辑: 我打开任务管理器以查看内存使用情况,当我按下按钮运行方法时,我注意到我的内存使用量每秒增加100mb.
编辑2: 在我的文件夹中,我有大约103张图像,每张图像大约100kb.我需要一个解决方案,无论文件夹中有多少图像都无关紧要.有人建议打开图像,做我的魔法,然后关闭它.我真的不明白他的意思是'亲密'.
有人可以推荐不同的方法吗?:)
编辑3: 仍然出现内存不足的异常,我根据建议更改了Picture.cs中的代码,但我没有想法.有帮助吗?
public override void getFileInformation(string filePath)
{
FileInfo fileInformation = new FileInfo(filePath);
using (var image = Image.FromFile(filePath))
{
if (fileInformation.Exists)
{
Name = fileInformation.Name;
FileType = fileInformation.Extension;
Size = fileInformation.Length;
CreationDate = fileInformation.CreationTime;
ModificationDate = fileInformation.LastWriteTime;
Height = image.Height;
Width = image.Width;
}
}
}
Run Code Online (Sandbox Code Playgroud)
此外,我现在应该开一个新的问题,这个问题已经增长了一点吗?
Art*_*hur 14
您没有在Image实例上调用Dispose.还要创建一次图像,然后提取数据.
也可以看看:
http://msdn.microsoft.com/en-us/library/8th8381z.aspx
编辑 如果复制了您的代码并使用我的图片库进行了测试.我的平均值 FileSize是每个文件2-3 MB.我已经执行了你的程序,它完全应该做到了.GC完全符合我的预期.
您的程序的内存总是大约11-35 MB私人工作集,提交大小稳定在43 MB.
我在1156个文件后中止了程序,总图像大小为2.9 GB.
因此,您必须有另一个原因导致内存不足异常.
这是我的程序输出和代码:
1133: Total Size = 2.842,11 MB
1134: Total Size = 2.844,88 MB
1135: Total Size = 2.847,56 MB
1136: Total Size = 2.850,21 MB
1137: Total Size = 2.853,09 MB
1138: Total Size = 2.855,86 MB
1139: Total Size = 2.858,59 MB
1140: Total Size = 2.861,26 MB
1141: Total Size = 2.863,65 MB
1142: Total Size = 2.866,15 MB
1143: Total Size = 2.868,52 MB
1144: Total Size = 2.870,93 MB
1145: Total Size = 2.873,64 MB
1146: Total Size = 2.876,15 MB
1147: Total Size = 2.878,84 MB
1148: Total Size = 2.881,92 MB
1149: Total Size = 2.885,02 MB
1150: Total Size = 2.887,78 MB
1151: Total Size = 2.890,57 MB
1152: Total Size = 2.893,55 MB
1153: Total Size = 2.896,32 MB
1154: Total Size = 2.898,92 MB
1155: Total Size = 2.901,48 MB
1156: Total Size = 2.904,02 MB
Run Code Online (Sandbox Code Playgroud)
源代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
namespace SharpLibrary_MediaManager
{
public abstract class BaseFile
{
public string Name { get; set; }
public string FileType { get; set; }
public long Size { get; set; }
public DateTime CreationDate { get; set; }
public DateTime ModificationDate { get; set; }
public abstract void getFileInformation(string filePath);
}
public class Picture : BaseFile
{
public int Height { get; set; }
public int Width { get; set; }
public Image Thumbnail { get; set; }
public override void getFileInformation(string filePath)
{
FileInfo fileInformation = new FileInfo(filePath);
using (var image = Image.FromFile(filePath))
{
if (fileInformation.Exists)
{
Name = fileInformation.Name;
FileType = fileInformation.Extension;
Size = fileInformation.Length;
CreationDate = fileInformation.CreationTime;
ModificationDate = fileInformation.LastWriteTime;
Height = image.Height;
Width = image.Width;
Thumbnail = image.GetThumbnailImage(40, 40, null, new IntPtr());
}
}
}
}
class Program
{
static void Main(string[] args)
{
string folderPath = @"C:\Users\arthur\Pictures";
DirectoryInfo folder = new DirectoryInfo(folderPath);
List<Picture> lol = new List<Picture>();
double totalFileSize = 0;
int counter = 0;
foreach (FileInfo x in folder.GetFiles("*.jpg", SearchOption.AllDirectories))
{
Picture p = new Picture();
p.getFileInformation(x.FullName);
lol.Add(p);
totalFileSize += p.Size;
Console.WriteLine("{0}: Total Size = {1:n2} MB", ++counter, totalFileSize / 1048576.0);
}
foreach (var p in lol)
{
Console.WriteLine("{0}: {1}x{2} px", p.Name, p.Width, p.Height);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您必须释放打开Image对象时使用的资源.
您可以调用Dispose,也可以在Using声明中创建图像
例如
public override void getThumbnail(string filePath)
{
using (Image image = Image.FromFile(filePath))
{
Thumbnail = image.GetThumbnailImage(40, 40, null, new IntPtr());
}
}
Run Code Online (Sandbox Code Playgroud)
并且由于您的类包含一个,Image您应该实现该IDisposable接口,因此您也可以在using语句中使用它.
我看到了一些问题.首先,您将随后调用CalculatePictureWidth和CalculatePictureHeight两次加载每个Image.其次,你似乎永远不会对缩略图做任何事情.第三,一旦完成从Image实例收集信息,就应该在Image实例上调用Dispose.