从PDF页面生成PNG并通过ImageList在ListView中显示它们
当用户选择要在列表视图中显示的另一个文件时 - >清除ImageList和ListView项(显而易见),并删除生成的图像文件。
删除时抛出异常:“进程无法访问文件'X.png',因为它正由另一个进程使用。”
previewImageList.Images.Clear();
previewListView.Items.Clear();
// folder containing the generated PNGs, created at runtime
string folderToDelete = Path.Combine(outputFolder, Path.GetFileNameWithoutExtension(selectedSong));
try
{
Directory.Delete(folderToDelete, true); // Image file "X.png" is used by another process
}
catch (Exception)
{}
发现解决方案: - 在删除所述PNG文件之前手动调用垃圾收集器似乎可以解决问题。
previewImageList.Images.Clear();
previewListView.Items.Clear();
string folderToDelete = Path.Combine(outputFolder, Path.GetFileNameWithoutExtension(selectedSong));
try
{
GC.Collect();
GC.WaitForPendingFinalizers();
Directory.Delete(folderToDelete, true);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
但是 因为我研究到目前为止这不是一件好事。 我可以选择调用垃圾收集器吗? 我需要删除PNG的原因是能够使用来自其他路径的PDF重用相应的文件名...
编辑其他详细信息 生成PNG: - 我这样使用ImageMagik:
startInfo = new ProcessStartInfo();
startInfo.FileName = "\"" + UtilitiesFolder + "\\convert.exe\"";
startInfo.Arguments = "\"" + selectedPDFFile.pdf" + "\" "
+ " -resample 168x140 \""
+ Path.Combine(outputFolder, selectedPDFFileShortName) + ".png" + "\"";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
process = Process.Start(startInfo);
process.WaitForExit(5000); // wait no more than 5 seconds
if (process.HasExited)
{ //good
}
else{
//abort everything
}
将图像加载到ImageList&的ListView:
void previewSelectedPresentation(string presentationName)
{
previewImageList.Images.Clear();
previewListView.Items.Clear();
DirectoryInfo dir = new DirectoryInfo(@"E:\\test\\" + presentationName);
foreach (FileInfo file in dir.GetFiles())
{
try
{
this.previewImageList.Images.Add(Image.FromFile(file.FullName));
}
catch
{
Console.WriteLine("This is not an image file");
}
}
for (int j = 0; j < this.previewImageList.Images.Count; j++)
{
ListViewItem item = new ListViewItem();
item.ImageIndex = j;
item.Text = (j + 1).ToString();
this.previewListView.Items.Add(item);
}
}
答案 0 :(得分:1)
问题解决了。 Per Hans Passant上面, (意译)
很久以前出了问题。我忘了在我之后丢弃图像 将它们添加到ImageList。
所以这是添加到ImageList的正确方法(请参阅原始问题进行比较) - 通过评论发出的更改:
void previewSelectedPresentation(string presentationName)
{
previewImageList.Images.Clear();
previewListView.Items.Clear();
DirectoryInfo dir = new DirectoryInfo(@"E:\\test\\" + presentationName);
foreach (FileInfo file in dir.GetFiles())
{
try
{
// these three lines have changed
Image slideImage = Image.FromFile(file.FullName); // change 1
this.previewImageList.Images.Add(slideImage); // change 2
slideImage.Dispose(); // change 3
}
catch
{
Console.WriteLine("This is not an image file");
}
}
for (int j = 0; j < this.previewImageList.Images.Count; j++)
{
ListViewItem item = new ListViewItem();
item.ImageIndex = j;
item.Text = (j + 1).ToString();
this.previewListView.Items.Add(item);
}
}
现在无需调用GC即可清理。 谢谢你帮我解决这个问题! 另外,有用的回答here。