图片压缩兼修改md5
概述
详细
一、程序截图
二、实现过程
实现思路:
1、编写界面
2、编写具体的按钮事件
3、重点是图片处理方法,然后将这些方法连接到按钮事件上面
4、测试运行。
具体代码如下:
1、入口是两个开始按钮的监听事件方法
- //选择图片所在目录
- private void button1_Click(object sender, EventArgs e)
- {
- FolderBrowserDialog dialog = new FolderBrowserDialog();
- dialog.Description = "请选择图片所在文件夹";
- if (dialog.ShowDialog() == DialogResult.OK)
- {
- if (string.IsNullOrEmpty(dialog.SelectedPath))
- {
- label3.Text = "文件夹路径不能为空";
- return;
- }
- label1.Text = dialog.SelectedPath;
- source = dialog.SelectedPath;
- }
- }
- //选择图片所在目录
- private void button2_Click(object sender, EventArgs e)
- {
- FolderBrowserDialog dialog = new FolderBrowserDialog();
- dialog.Description = "请选择输出文件夹";
- if (dialog.ShowDialog() == DialogResult.OK)
- {
- if (string.IsNullOrEmpty(dialog.SelectedPath))
- {
- label3.Text = "文件夹路径不能为空";
- return;
- }
- label2.Text = dialog.SelectedPath;
- output = dialog.SelectedPath;
- }
- }
- //单层目录开始按钮监听
- //按方法用于选择单个目录下的所有图片文件,并调用ApplyWaterMark方法进行图像处理
- private void btnOk_Click(object sender, EventArgs e)
- {
- label3.ForeColor = Color.Black;
- if (string.IsNullOrEmpty(source))
- {
- label3.ForeColor = Color.Red;
- label3.Text = "请选择原文件夹";
- return;
- }
- if (string.IsNullOrEmpty(output))
- {
- label3.ForeColor = Color.Red;
- label3.Text = "请选择输出文件夹";
- return;
- }
- var files = Directory.GetFiles(source);
- foreach (var file in files)
- {
- ApplyWaterMark(file, output);
- label3.Text = "正在修改" + file;
- }
- label3.ForeColor = Color.Red;
- label3.Text = "完成";
- source = string.Empty;
- output = string.Empty;
- }
- //双层目录开始按钮监听
- //该方法用于父目录下还有一层子目录,子目录下才是图片文件的情况。可以批量修改多个文件夹的图片
- private void btnOk2_Click(object sender, EventArgs e)
- {
- label3.ForeColor = Color.Black;
- if (string.IsNullOrEmpty(source))
- {
- label3.ForeColor = Color.Red;
- label3.Text = "请选择原文件夹";
- return;
- }
- if (string.IsNullOrEmpty(output))
- {
- label3.ForeColor = Color.Red;
- label3.Text = "请选择输出文件夹";
- return;
- }
- var dirs = Directory.GetDirectories(source); //先打开父目录
- foreach (var dir in dirs) //遍历子目录
- {
- foreach (var file in Directory.GetFiles(dir))
- {
- var dirInfo = new DirectoryInfo(dir);
- var dirName = dirInfo.Name;
- var outputDirName = Path.Combine(output, dirName);
- ApplyWaterMark(file, outputDirName);
- label3.Text = "正在修改" + file;
- }
- }
- label3.ForeColor = Color.Red;
- label3.Text = "完成";
- source = string.Empty;
- output = string.Empty;
- }
2、图像处理的核心代码
- private void ApplyWaterMark(string file, string dir)
- {
- try
- {
- var info = new FileInfo(file);
- var name = info.Name;
- Image Im = Image.FromFile(file);
- var rate = (int)compressRate.Value == 0 ? 1 : (int)compressRate.Value;//读取图片压缩控件设置的倍数,最大值10
- var newImage = new Bitmap(Im,Im.Width/rate,Im.Height/rate);//源图片长宽除以该倍数,缩放图片
- Graphics g = Graphics.FromImage(newImage);
- // 创建 solid brush 往图片写水印
- Brush myBrush = new SolidBrush(Color.FromArgb(1, Color.LightSteelBlue));
- var f = new Font(FontFamily.GenericSerif, 1);
- var x = (int)(coX.Value); //读取水印坐标设置的X轴值
- var y = (int)(coY.Value); //读取水印坐标设置的Y轴值
- g.DrawString(".", f, myBrush, new Point(x, y));
- if (!Directory.Exists(dir)) //创建图片的输出目录
- {
- Directory.CreateDirectory(dir);
- }
- //初始化jpg图片解码器
- ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);
- Encoder myEncoder = Encoder.Quality;
- EncoderParameters myEncoderParameters = new EncoderParameters(1);
- var qualityNum = quality.Value; //读取图片质量控件设置的值,最大值为100
- EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, (long)qualityNum);
- myEncoderParameters.Param[0] = myEncoderParameter;
- newImage.Save(Path.Combine(dir, name), jpgEncoder, myEncoderParameters);
- Im.Dispose();
- newImage.Dispose();
- g.Dispose();
- myBrush.Dispose();
- }
- catch (Exception ex)
- {
- File.AppendAllText("error.txt", dir + "," + ex.Message);
- }
- }
- private ImageCodecInfo GetEncoder(ImageFormat format)
- {
- ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
- foreach (ImageCodecInfo codec in codecs)
- {
- if (codec.FormatID == format.Guid)
- {
- return codec;
- }
- }
- return null;
- }
三、项目结构图
四、其他补充
说明:关于压缩图片,有时候缩放尺寸更好,有时候降低图片质量更好,有时候两个选项配合起来用,具体自己调节!
下面举个自己压缩图片的例子:
原图片
压缩后
压缩了近10倍的大小,但是图片的各项参数都没改变,压缩后的图片和原图片一样清晰。
压缩的时候只是将图片质量(quality)控件的值设置为50,就达到了这样的效果。当然,不是每张图片都是这样修改,有些图片可能修改尺寸,而不修改图片质量更好。
注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权
图片压缩兼修改md5的更多相关文章
- Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩
目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...
- gulp-imagemin图片压缩----gulp系列(三)
本节实现图片压缩,在实现压缩前,先配置images任务,设置源目录和输出目录. 在系列(二)代码的基础上,再进行扩展. 1.找到gulp->config.js,对images进行源目录(src- ...
- Android 调用jepg库进行图片压缩,保持图片不失真
1. 浅谈为什么Android和iOS图片质量差距那么大? 首先来说,作为一个安卓狗,机器当然用的是安卓的手机.现在的安卓手机大多数都会以高清拍照,动不动就几千万柔光相机来吸引各种买家.买来后,拍照发 ...
- 好久没发贴了,最近捣鼓了个基于node的图片压缩小网站解析。
看了下,距离上次发帖都是去年10月份的事,忙于工作的我很少跑博客园里面来玩了. 做这个小网站的初衷是 https://tinypng.com/ 这个网站有时候访问很慢,然后自己去研究了下图片压缩. 网 ...
- Android 中图片压缩分析(上)
作者: shawnzhao,QQ音乐技术团队一员 一.前言 在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种:其一是质量压缩,其二是下采样压缩. 前者是在不改变图片尺寸的情 ...
- android-xBuild apk差分与合成,zip差分与合成,lua打包,apk打包,png/jpg图片压缩
android-xBuild 是一项集成了apk差分与合成,zip差分与合成,lua打包.apk打包,png/jpg图片压缩五大功能的开源项目 (github地址:https://github.com ...
- iOS 图片裁剪与修改
最近做的项目中需要上传头像,发表内容的时候也要涉及到图片上传,我直接用的原图上传,但是由于公司网络差,原图太大,老是加载好久好久,所以需要把原图裁剪或者修改分辨率之后再上传,找了好久,做了很多尝试才解 ...
- Gulp 之图片压缩合并
同事需要处理很多的图片,由于UI那边提供图片比较大,为了性能好一点,程序包小一点,因此希望我帮忙做成小程序来完成此工作. 其实之前做过一个grunt写的图片压缩合并工具,当时是为了处理270多个国家/ ...
- (转)Android学习-使用Async-Http实现图片压缩并上传功能
(转)Android学习-使用Async-Http实现图片压缩并上传功能 文章转载自:作者:RyaneLee链接:http://www.jianshu.com/p/940fc7ba39e1 让我头疼一 ...
随机推荐
- java验证openssl生成的ssl证书和私钥是否匹配
最近有一个需求上传ssl证书和私钥,但是上传之前需要验证ssl证书和私钥是否正确,其中的业务逻辑涉及到以下几点: 一.读取ssl证书,读取ssl证书公钥 要实现该功能比较简单,java里面 ...
- Educational Codeforces Round 11 D. Number of Parallelograms 暴力
D. Number of Parallelograms 题目连接: http://www.codeforces.com/contest/660/problem/D Description You ar ...
- Pandas中Series和DataFrame的索引
在对Series对象和DataFrame对象进行索引的时候要明确这么一个概念:是使用下标进行索引,还是使用关键字进行索引.比如list进行索引的时候使用的是下标,而dict索引的时候使用的是关键字. ...
- Current limiter allows large USB bypass capacitance
The USB (Universal Serial Bus) specification requires a connected USB device to present a load to th ...
- 利用Lucene与Nutch构建简单的全文搜索引擎
文章地址 1.简介 本次实现分为两个部分,第一个部分是利用Lucene构建一个全文的搜索引擎,另外一部分则是利用Nutch实现同样的功能.由于Lucene并不是一个可以直接运行的程序,且不具备爬虫和文 ...
- EventStore .NET API Client在使用线程池线程同步写入Event导致EventStore连接中断的问题研究
最近,在使用EventStore的.NET Client API采用大量线程池线程同步写入Event时(用于模拟ASP.NET服务端大并发写入Event的情况),发现EventStore的连接会随机中 ...
- 如何使用keepalived实现nginx双机热备
1.linux安装方法:yum -y install keepalived 配置开机启动:sudo chkconfig keepalived on 查看keepalivede运行日志:/var/lo ...
- HTML5+JS手机web开发之jQuery Mobile初涉
一.起始之语 我一直都是在PC上折腾网页的,这会儿怎么风向周边捣鼓起手机网页开发呢?原因是公司原先使用Java开发的产品,耗了不少人力财力,但是最后的效果却不怎么好.因为,Android系统一套东西, ...
- Android -- 启动模式
Android的启动模式分为四种: standard 模式启动模式,每次激活Activity时都会创建Activity,并放入任务栈中. singleTop 如果在任务的栈顶正好存在该Activity ...
- C# 解决无法识别的属性 configProtectionProvider
在使用.Net自身提供的加密本配置文件后再用System.Configuration.ConfigurationManager.AppSettings["key"]获取值时会出现“ ...