C#照片批量压缩小工具

原文:C#照片批量压缩小工具

做了一个照片批量压缩工具,其实核心代码几分钟就完成了,但整个小工具做下来还是花了一天的时间。中间遇到了大堆问题,并寻求最好的解决方案予以解决。现在就分享一下这个看似简单的小工具所使用的技术。

软件界面如下:

要做真实场景的测试,拿的都是单反照的大相片:图片尺寸3888*2592  图片大小5.37M:

其中遇到的问题与解决方案分享:

1.用listview显示图片缩略图非常慢的问题

这个问题是始料未及的,如果不做也可以,但是没有缩略图就有损软件体验,这是所有最求完美的程序员所不能容忍的,我当然也不例外。

最初的代码如下:(此方法加载每张5M左右的图片需要200-500ms)

+ ?




listView1.Items.Clear();

imageList1.Images.Clear();

DirectoryInfo TheFolder = new
DirectoryInfo(folderBrowserDialog1.SelectedPath);//文件路径

List<string> ImgNames = new
List<string>();

string
allowImg = ".jpg.jpeg.png.bmp";

FileInfo[] Files = TheFolder.GetFiles();

for (int
i = 0; i < Files.Length; i++)//遍历文件夹

{

    if
(Files[i].Length > 0 &&allowImg.IndexOf(Files[i].Extension.ToLower())>-1)//或者jpg,png 文件大小要大于0且是图片文件

    {

        Image image = Image.FromFile(Files[i].DirectoryName + "\\"
+ Files[i].Name);    //获取文件                

        ImgNames.Add(Files[i].Name);//添加文件名

        imageList1.Images.Add(image);//添加图片

    }

}

//初始化设置

this.listView1.View = View.LargeIcon;

this.listView1.LargeImageList = this.imageList1;

//开始绑定

this.listView1.BeginUpdate();

for
(int
i = 0; i < ImgNames.Count; i++)

{

    ListViewItem lvi = new
ListViewItem();

    lvi.ImageIndex = i;

    lvi.Text = ImgNames[i];

    this.listView1.Items.Add(lvi);

}

this.listView1.EndUpdate();

  解决办法是用微软提供的Windows
API Code Pack
1.0.1库,通过该库可以直接使用到win7/vista/win8系统的一些特性功能,如资源管理器、桌面、任务栏等等。详细介绍见官方主页

本程序使用WindowsApiCode完成对文件夹下的图片迅速建缩略图的代码如下:

先在界面上添加一个该库提供的explorerBrowser控件,然后初始化该控件:

?




//设置图片展示控件属性

explorerBrowser1.ContentOptions.ViewMode = ExplorerBrowserViewMode.List;

explorerBrowser1.NavigationOptions.PaneVisibility.Navigation = PaneVisibilityState.Hide;

explorerBrowser1.NavigationOptions.PaneVisibility.CommandsView = PaneVisibilityState.Hide;

explorerBrowser1.NavigationOptions.PaneVisibility.CommandsOrganize = PaneVisibilityState.Hide;

explorerBrowser1.NavigationOptions.PaneVisibility.Commands = PaneVisibilityState.Hide;

explorerBrowser1.SelectionChanged += new
EventHandler(explorerBrowser1_SelectionChanged);

完成打开文件夹并显示图片缩略图的代码非常简单:

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

//打开图片文件夹

 private
void btnOpenDir_Click(object
sender, EventArgs e)

 {

     // 创建打开文件夹对话框

     CommonOpenFileDialog cfd = new
CommonOpenFileDialog();

     // 设置对话框属性

     cfd.IsFolderPicker = true;

     cfd.AllowNonFileSystemItems = true;

     // 弹出对话框并返回用户的选择

     CommonFileDialogResult result = cfd.ShowDialog();

     //如果用户确定

     if
(result == CommonFileDialogResult.Ok)

     {

         // 获取选择对象的ShellObject形式

         ShellObject resultItem = cfd.FileAsShellObject;

         //用explorerBrowser控件显示图片列表

         explorerBrowser1.Navigate(resultItem);

     }

 }

采用这种方法打开图片缩略图列表时间可以忽略不计。

2.好看的图片界面库

从前面的界面可以看出,本工具的界面并不丑,可以说还很精美,这也是花了心思的。

本工具的界面我采用的是

官方主页为http://www.componentfactory.com/

3.充分利用多核并行计算,提高图片处理速度

处理批量任务当然要考虑速度,否则就失去了工具的意义了

.netFrameWork4.0里面提供了Parallel系列、Task系列来支持并行运算,让并行计算变得如此简单(为什么不跟着微软走呢,后悔了吧
^_^)。

并行指的是利用现在的CUP多核,同时开启多个任务。跟以往的并发计算不同的是,并发的多个线程其实并非真正同时在运行,他们只是按照时间片,走走停停,逻辑上在同时进行,而并行则是在多个完全独立的核上同时运行任务,是真正的同时在跑。

本程序中并行进行图片压缩的代码如下:

?




ParallelOptions po = new
ParallelOptions();

po.MaxDegreeOfParallelism = 15; //最多并发15个任务

//并行进行图片压缩

Parallel.ForEach(imgtoComp, po, (o) =>

{

    System.Drawing.Image sourceImg = System.Drawing.Image.FromFile(o.ParsingName);

    int
iWidth = 0;

    int
iHeight = 0;

    if
(rbtper.Checked)

    {

        int
per = int.Parse(txtper.Text);

        iWidth = sourceImg.Width * per / 100;

        iHeight = sourceImg.Height * per / 100;

    }

    if
(rbtheight.Checked)//最大高度

    {

        iHeight = int.Parse(txtheight.Text);

        iWidth = iHeight * sourceImg.Width / sourceImg.Height;

    }

    if
(rbtwidth.Checked)//最大宽度

    {

        iWidth = int.Parse(txtwidth.Text);

        iHeight = iWidth * sourceImg.Height / sourceImg.Width;

    }

    System.Drawing.Image ThumbImg = ImgCompress.GetImageThumb(sourceImg, iWidth, iHeight);

    if
(rbtpng.Checked) ThumbImg.Save(FileSavePath+o.Name,System.Drawing.Imaging.ImageFormat.Png);

    if
(rbtgif.Checked) ThumbImg.Save(FileSavePath + o.Name, System.Drawing.Imaging.ImageFormat.Gif);

    if
(rbtjpg.Checked) ThumbImg.Save(FileSavePath + o.Name, System.Drawing.Imaging.ImageFormat.Jpeg);

    sourceImg.Dispose();

    ThumbImg.Dispose();

    ifinish++;

    this.Invoke(this.mysetFinish, new
Object[] { ifinish }); //刷新进度条等

});

这里主要强调一下并发任务数量的设置、以及资源的显示释放。

并发数量通过ParallelOptions参数的MaxDegreeOfParallelism来设置,这里必须设置,否则几百张5M的图片同时跑,立马内存就占满了。

资源的显式释放:sourceImg.Dispose();  ThumbImg.Dispose(); 
这点也非常重要,处理大图片是非常耗内存的,测试过程中就因为没有显式释放内存,偷懒想着.net的自动垃圾回收机制会帮忙善后,结果跑到40多张图片的时候就内存不足了。显式处理资源释放后,压缩图片的速度也因为空余的内存比较多而变快了。

下载本程序  Demo

C#照片批量压缩小工具,码迷,mamicode.com

时间: 2024-10-28 19:07:07

C#照片批量压缩小工具的相关文章

【游戏开发】Excel表格批量转换成CSV的小工具

一.前言 在工作的过程中,我们有时可能会面临将Excel表格转换成CSV格式文件的需求.这尤其在游戏开发中体现的最为明显,策划的数据文档大多是一些Excel表格,且不说这些表格在游戏中读取的速度,但就论占用内存来说,同样的数据量Excel表格所占用的内存要远远大于CSV,因此将Excel转换成CSV势在必行.如果单单转换一个Excel表格还好,直接另存为就搞定的,但是如何将一个文件下的N个Execl表格转成CSV呢?今天马三就来和大家一起用Python撸一个Excel表格批量转换CSV的小工具—

相片批量压缩和改名小工具

您是否有过从相机中取出的照片保存起来太占空间.上传太费力的经历呢? 这个小工具由此而生,特点如下: 1.本软件提供多种图片的压缩功能.目前支持图片格式有:BMP JPG GIF PNG. 2.文件列表显示支持多文件或文件夹拖拽功能.保存路径支持文件夹拖拽,保存格式增加原格式功能,增加暂停.清空列表功能 3.增加图片最大宽度设置,增加文件更名器功能 转换选项:保存路径:转换后的图像文件保存到指定路径.保存格式:转换后的图像文件保存的格式.默认不改变现有图片格式.最大宽度:转换后的图片最大宽度为选中

如何将图片批量压缩?全面盘点这几种小方法

写在前面:现在的人们都喜欢用自己手机里的相机来记录自己生活中的点滴美好,而拍照成为人们记录自己生活的最常用的一个方式,这样当时间过去也会记得自己之前曾去过哪些地方,可是照片多了之后也很烦恼,图片太多,就容易出现体积过大的,在传输的时候特别麻烦,这就需要将图片进行压缩,如果图片过多,就需要进行批量压缩,那么如何将图片批量压缩?今天就来为大家爱全面盘点这几种小方法.一.软件压缩推荐指数:★★★★★借助工具:迅捷压缩软件介绍:迅捷压缩软件是一款操作简单,快捷高效的图片压缩,视频压缩,PDF压缩软件,能

用Photoshop软件实现批量压缩照片

前提:手头有 "大" 照片,出于某种原因想把它变成 "小" 照片:电脑刚好安装有PS软件. 需知:如果您的压缩需求仅限于降低图片品质,降低图片像素,那么建议您采取方案一,否则采取方案二. 两种方案均在PScc2018上正确运行. 方案一:使用PS软件自带的脚本 文件=>脚本=>图像处理器 选择要处理的图像:勾选并选择您的文件夹 选择位置以存储处理的图像:勾选并选择您的文件夹 文件类型:修改您希望的品质(0--12)和像素 例如: 点击运行即可开始压缩 方

用C#Winform写个简单的批量清空文件内容和删除文件的小工具

用C#Winform写个简单的批量清空文件内容和删除文件的小工具 本文介绍这个简单得不能再简单的小项目.做这个项目,有以下目的. 1 当然是做个能用的工具 2 学习使用Github 关于用VS2013创建一个项目并添加到Github的教程,请参考(http://www.admin10000.com/document/4004.html).简单来说,就是先用VS创建项目:然后在Github网站上创建一个Respo(本项目的代码托管项目),记下(https://*.git)那个地址:最后用"提交&q

Python实现linux/windows通用批量‘命令/上传/下载’小工具

这阵子一直在学python,碰巧最近想把线上服务器环境做一些规范化/统一化,于是便萌生了用python写一个小工具的冲动.就功能方面来说,基本上是在"重复造轮子"吧,但是当我用这小工具完成了30多台服务器从系统层面到应用层面的一些规范化工作之后,觉得效果还不算那么low(高手可忽略这句话~~),这才敢拿出来跟小伙伴们分享一下. (注:笔者所用为python版本为3.5,其他版本未经测试~~) 其实很简单,就"一个脚本"+"server信息文件"实

Linux批量管理服务器小工具--PSSH

Linux批量管理服务器小工具--PSSH 一.简介 pssh -- parallel ssh program pssh  is  a program for executing ssh in parallel on a number of hosts.  It provides features such as sending input to all of the processes, passing a password to ssh, saving output to files, an

Windows平台软件推荐:神器小工具(骨灰级)

底层工具 "If you know how to use Process Monitor competently, people of both sexes will immediately find you more attractive." – Scott Hanselman Ultimate Boot CD 和 Ultimate Boot CD for Windows  – 这些光盘是程序员修电脑时的必备工具,毕竟你可没那么多钱给给每个电脑坏掉的亲戚买新机,不是么? Hiren'

配置文件和配置表定期备份小工具

现在维护的配置文件/表都是人手工备份,上次某机器宕机,想在别的机器上拉起应用,去找备份的时候,发现最近的备份还是去年的,因此有了这个想法写这么一个小工具才进行定期备份.其实细极思恐,每天备份一下还是很有必要的,出事了,也能找到是哪天开始的不是? 设计的思路还是先把哪些机器的文件.哪个数据库的表需要备份,放入数据库中,然后弄一个shell,在某个机器上启动这个shell,使用ftp去备份配置文件,使用exp去dmp数据库文件,完成备份. 首先是数据库设计部分,需要两张表: "机器表":