65.9K
CodeProject 正在变化。 阅读更多。
Home

基于 C# 的缩略图查看器

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.53/5 (19投票s)

2007年2月25日

CPOL

4分钟阅读

viewsIcon

97066

downloadIcon

3891

一个基于 C# 的缩略图查看器,使用 BackgroundWorker 在后台加载图像。

JThumbnailView Demo project

引言

很多时候,我们需要将一个目录中的图片显示为缩略图。这个控件 JThumnailView 就能做到这一点。这个控件的额外功能是它使用后台工作者异步加载图像。

背景

这一切都始于我想把一些照片通过电子方式寄回家。当然,我可以通过电子邮件发送,但大多数时候会先进行zip压缩。当我看到父母在以后查看时很难找到他们保存照片的位置时,我意识到我需要为他们提供一些可以由我控制的东西。因此,我开始开发一个应用程序,一旦安装在机器上,它将作为自动图片下载器和基本查看器。因此,我面临着以下挑战:

  1. 如何实现自动下载?我的答案是 edtFTPnet 组件,我可以使用它从 FTP 服务器下载文件。然而,这带来了另一个问题:每次我想发送新照片时,我都需要一种机制,能够透明地完成,无需任何手动干预。那时我决定使用一个 XML 文件,应用程序将读取它并执行必要的动作。然而,一旦我开始开发 XML 文件,我想要加密它并给它一个不同的扩展名。因此,我使用 DESCryptoServiceProvider 对文件进行加密/解密。现在,我所要做的就是发送我的文件(它有一个*.pfi扩展名)并提供密码。当双击这个文件时,它会要求输入密码,然后它将自动从我的 FTP 站点下载照片。
  2. 我的第二个挑战是提供一个简单的照片查看器在同一个应用程序中,这样用户就不必担心照片存放在哪里。为此,我需要两个组件:一个类似资源管理器的文件夹查看器和一个缩略图查看器。那时我得到了 Rajesh Lal 编写的 WindowsExplorer 组件。虽然我必须做一些小的修改以适应我的需求,但它为我节省了很多时间。
  3. 唯一剩下的就是缩略图查看器。我找了一个好的,但大多数都是为 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() 方法如上所述创建了一个默认缩略图。实际的缩略图是在 BackgroundWorkerDoWork() 事件中绘制的。缩略图使用通常的图形方法绘制。

关注点

使用 BackgroundWorker 确实大大提高了查看器的效率。另一个有趣的事情是使用了 Graphics 对象的 PixelOffSetModeInterpolationMode。当我第一次绘制缩略图时,我无法匹配 Windows Explorer 缩略图中图像的清晰度。那时我尝试了各种 PixelOffSetModeInterpolationMode。我通过以下组合实现了期望的结果:

PixelOffsetMode = PixelOffsetMode.None;

InterpolationMode = InterpolationMode.HighQualityBicubic;

历史

版本 1.1

感谢所有宝贵的评论,我已经修改了组件以包含更多检查:)。我还修改了演示以包含一个最小化的图片查看器。再次感谢大家,特别是 Michael,感谢他的特别关注和反馈。我还没有真正测试过动态释放和创建,所以不确定问题是否仍然存在。

© . All rights reserved.