照片分类一键归档

照片分类一键归档

开发工具:MS C# 2005

程序源码可以在文件中下载 myphoto.rar

 

通过本文可以了解:

1、对系统各盘进行自动搜索,只搜索“移动盘”上的照片;

2、了解JPG的Exif信息,提取日期进行归档;

3、建立快捷方式,完成“一键同步”功能。

4、实现工具的命令行运行与图形界面“比翼双飞”效果。

 

现在流行“驴行”,出去玩了几天之后,回来后首要事情就是把照片归档到电脑中,我们习惯于把照片在电脑中按日期建立目录来进行存放,有时是多天的或者是多人的都按此方法进行归集时,就到遇到:每人的相机需要按日期进行多次归集;或者是自己的相机,也要在一大堆的照片中去查找一次,比较麻烦。现在我们的工具要完成:

1、 照片自动归集,桥归桥,路归路,哪天的照片存到哪天目录。

2、 可以创建快捷方式,完成我们的一键归集功能。

接下看看工具使用时是否满足要求,首先打开我们的程序后,如下图(图001)所示:

 

先设置归档目录,再点“同步“按钮,就可以看到在d:\photo目录下面,在年份基础上再按日期完成照片的归档功能:

 

在此基础上,点按钮“创建一键快捷方式“,工具还能在桌面上建立相应的快捷方式,它的属性如下,如图003:

 

里面还有快捷键,当然如果预定义的快捷键不方便,那就自定义一个吧。好了,我们就看看这个工具“如何制造”吧。

简单界面

我们需要有一个主界面来完成一些基本功能,如图001所示中,在界面的基本功能,其实就是三个按钮,分别是:

设置归档目录:这个最简单,其实是完成目录选择功能;

同步:在同步功能中调用指定类完成照片同步功能。

创建一键快捷方式:就是在桌面上建立相应的快捷方式,同时指定了快捷键的功能。

命令行开关是一键启动的引子

在图003中我们可以看到,快捷方式有命令行和快捷键的定义,就需要在程序中提供此功能。即程序必须支持命令行,同时还有建立快捷方式的功能。

所以我们要利用命令行的参数信息,即命令行来操作我们程序的运行方法,把MAIN程序改造成这样的效果(以下只是代码的关键部分):

        static void Main(string[] args){...

            RunForm = new FormPhoto();

            RunForm.Show();

            if (args.Length == 0)

                Application.Run(RunForm);

            else

                if (args[0].Trim().ToLower() == "-a"){  //表示自动运行时的参数,可能对比图3

                    RunForm.rtb_dir.Text = args[1].Trim();

                    oprate.BeginOprate(args[1].Trim(), "", RunForm.rtb_infos);

其中Formpohto中的rtb_infos,rtb_dir的属性都改成PUBLIC,方便外部类的调用。这样在程序的分支处理上就达成我们目标,即使用命令行时能自动运行,并且完成后自动退出,即没有Application.Run的功能(当然有错误时能够提醒使用者是最好的);不使用命令行时需要交互运行。

创建快捷方式及快捷键一键启动实现

在使用基本类PhotoOparate和FormPhoto完成功能框架后,定义及创建快捷方式就很重要,在C#中建立快捷方式比较简单,按钮“创建一键快捷方式”对应的关键代码:

            shortcut.TargetPath = System.Reflection.Assembly.GetExecutingAssembly().Location;

           shortcut.Arguments = "-a " + args[0]; //直接建立快捷方式 ......

            shortcut.Description = "数码相机照片一键归档(按日期)";

            shortcut.Hotkey = "CTRL+F7";

            shortcut.Save();

点按钮后在桌面上建立“一键归档”的快捷方式,其快捷键是“CTRL+F7”,如果要让用户自定义这个快捷键,不“砖业”一点,可以让用户输入快捷键名的字符串如“F12”,或者是在快捷方式中修改。当然要“砖业”,则要如快捷方式那样通过捕捉用户按键来进行定义。

使用命令行的方式,如果想做多个归档就可以建立多个快捷方式,都能实现“一键归档”的目的。

图片归档核心(函数PhptoOparate.BeginOprate)

图片归档类是PhptoOparate,说到图片就和我们归档所在的目录结构有很大关系,在图片扫描过程就需要分成三步处理。

1、  移动盘的扫描:只要利用:

DriveInfo[] MyDrives = DriveInfo.GetDrives();

然后取出根据DriveInfo的DriveType等于 DriveType.Removable即表示移动盘,稍稍对系统注意一下,就会发现,通过数据线连相码相机或者是读卡器连接的存储卡一般都是此性质。

2、  通盘搜索图片文件(函数fun_listfiles):

本函数利用指定目录的遍历功能,查找移动盘上的所有图片文件,对于遍历功能并不复杂,在笔者《用C#打造像Windows7那样的搜索》文章中已有介绍。在找到图片文件时,进行相应的处理最为重要,即在此过程中调用了函数fun_imageinfo,完成照片的归档功能。

3、  核心:图片归档我作主(函数fun_imageinfo):

在图片归档时,由于需要照片拍摄日期。在处理时取它的Exif信息就很重要,使用:

         image = Image.FromFile(as_fullpath);

取得图片数据源,这样我们就需要定义JPEG图片文件中Exif的结构信息,通过ExIfMetaData.cs中的重要函数GetExifCore来取得完整的exif信息,最后通过medaData.DatePictureTaken.DisplayValue来取得实际的拍摄日期。这样在图片归档时目标就确定了。里面有年份和日期,如果最终归档目录中有相应的年份,只要多做一步,就更人性化了,比如:

ls_photopath = as_photo + "\\" + ls_datetime.Substring(0, 4);

if (!System.IO.Directory.Exists(ls_photopath))  //此处检测照片归档是否按年份处理

就是判断是否有年份存在,存在年份时把目录再组织深一层即可。

再遍历指定年份的目录,找到归档目录的前8位是否是我们需要的日期,因为最终存档的日期格式中仍然存在相应的位置说明,比如“20091228-湿地”这样的目录名,如果不存此类目录,自动建立目录名就是“20091228”这样的日期了。具体的程序实现可看源码,并加以相应的注释。由于在实现中,还会根据建立相应的目录缓存,当属于同一日期的图片,还会在缓存中查找,找到时直接使用目录存入即可。细节就可以看源码体会一下了。

 

这样自动归档的工具就基本上做完,不过在“一键归档”使用时,由于源图实际上每个都至少读取一遍,因此性能上仍有需要改进之处。一般情况下拍摄日期如果和文件日期没有差异,我们可以改造成使用文件日期的方法来加快进度,或者可以利用其它更快速的方法提取JPEG的EXIF中的日期。同时除JPG之外的文件,目前也未做自动归档。但是有创意和源码在,只要有更多兴趣,自然可以把工具改造得更有价值。

 

2009年12月28日于浙江杭州

 

posted @ 2010-02-26 12:35  妖精总比想象多  阅读(2089)  评论(2编辑  收藏  举报