基于 C# 的缩略图查看器






3.53/5 (19投票s)
一个基于 C# 的缩略图查看器,使用 BackgroundWorker 在后台加载图像。
引言
很多时候,我们需要将一个目录中的图片显示为缩略图。这个控件 JThumnailView
就能做到这一点。这个控件的额外功能是它使用后台工作者异步加载图像。
背景
这一切都始于我想把一些照片通过电子方式寄回家。当然,我可以通过电子邮件发送,但大多数时候会先进行zip压缩。当我看到父母在以后查看时很难找到他们保存照片的位置时,我意识到我需要为他们提供一些可以由我控制的东西。因此,我开始开发一个应用程序,一旦安装在机器上,它将作为自动图片下载器和基本查看器。因此,我面临着以下挑战:
- 如何实现自动下载?我的答案是 edtFTPnet 组件,我可以使用它从 FTP 服务器下载文件。然而,这带来了另一个问题:每次我想发送新照片时,我都需要一种机制,能够透明地完成,无需任何手动干预。那时我决定使用一个 XML 文件,应用程序将读取它并执行必要的动作。然而,一旦我开始开发 XML 文件,我想要加密它并给它一个不同的扩展名。因此,我使用
DESCryptoServiceProvider
对文件进行加密/解密。现在,我所要做的就是发送我的文件(它有一个*.pfi扩展名)并提供密码。当双击这个文件时,它会要求输入密码,然后它将自动从我的 FTP 站点下载照片。 - 我的第二个挑战是提供一个简单的照片查看器在同一个应用程序中,这样用户就不必担心照片存放在哪里。为此,我需要两个组件:一个类似资源管理器的文件夹查看器和一个缩略图查看器。那时我得到了 Rajesh Lal 编写的
WindowsExplorer
组件。虽然我必须做一些小的修改以适应我的需求,但它为我节省了很多时间。 - 唯一剩下的就是缩略图查看器。我找了一个好的,但大多数都是为 ASP.NET 设计的。最后,我找到了一个,但又是基于 VC++ 的。那时我决定自己写一个。我把它做成一个控件,以便其他人可以重复使用。本文介绍了为这个目的创建的
JThumnailView
组件。对于那些想要应用程序完整版本的人,请通过电子邮件与我联系。我将非常乐意提供它(尽管它仍处于 beta 阶段!)。
Using the Code
这个组件非常简单易懂。它继承自标准的 ListView
控件,这样我就不必担心滚动、排序等问题了:)。
以下是主要属性
public int ThumbNailSize; //default value: 95
默认值为 95(Windows Explorer 似乎使用了这个大小,所以我将其设为默认值)。
public int ThumbBorderColor; //default value: Color.Wheat
如果希望缩略图具有不同的边框,请设置此项。
public string FolderName; //default value: Application folder
这是从哪个目录加载缩略图的。该组件还有一个名为 CanLoad
的属性,应将其设置为 true
来加载图像。这应该在窗体的构造函数中设置为 true
。
大多数缩略图查看器的一个主要问题是,如果一个目录中的文件数量很多,那么查看器将花费很长时间来加载。为了避免这种情况,我使用的技术是创建一个默认缩略图,它只是一个缩略图大小的正方形,并将其设置为所有项目的图像索引。这将给用户一种缩略图已加载的印象。然后,实际的缩略图使用 BackgroundWorker
在后台加载。
private BackgroundWorker myWorker = new BackgroundWorker();
项目的加载由 ReloadItems()
方法处理。
private void ReLoadItems()
{
BeginUpdate();
Items.Clear();
LargeImageList.Images.Clear();
AddDefaultThumb();
string strFilter = "*.jpg;*.png;*.gif;*.bmp";
List fileList = new List();
string[] arExtensions = strFilter.Split(';');
foreach (string filter in arExtensions)
{
string[] strFiles = Directory.GetFiles(folderName, filter);
fileList.AddRange(strFiles);
for (int i = 0; i < strFiles.Length; i++)
{
FileInfo fiTemp = new FileInfo(strFiles[i]);
Items.Add(fiTemp.Name, 0).Tag = strFiles[i]; }
}
fileList.Sort();
EndUpdate();
if (myWorker != null) { myWorker.RunWorkerAsync(fileList); }
}
}
AddDefaultThumb()
方法如上所述创建了一个默认缩略图。实际的缩略图是在 BackgroundWorker
的 DoWork()
事件中绘制的。缩略图使用通常的图形方法绘制。
关注点
使用 BackgroundWorker
确实大大提高了查看器的效率。另一个有趣的事情是使用了 Graphics
对象的 PixelOffSetMode
和 InterpolationMode
。当我第一次绘制缩略图时,我无法匹配 Windows Explorer 缩略图中图像的清晰度。那时我尝试了各种 PixelOffSetMode
和 InterpolationMode
。我通过以下组合实现了期望的结果:
PixelOffsetMode = PixelOffsetMode.None;
InterpolationMode = InterpolationMode.HighQualityBicubic;
历史
版本 1.1
感谢所有宝贵的评论,我已经修改了组件以包含更多检查:)。我还修改了演示以包含一个最小化的图片查看器。再次感谢大家,特别是 Michael,感谢他的特别关注和反馈。我还没有真正测试过动态释放和创建,所以不确定问题是否仍然存在。