图片压缩兼修改md5
概述
一个桌面程序,能修改图片的尺寸和质量,并且通过加水印的方式修改图片的md5等值。
详细
一、程序截图
二、实现过程
实现思路:
1、编写界面
2、编写具体的按钮事件
3、重点是图片处理方法,然后将这些方法连接到按钮事件上面
4、测试运行。
具体代码如下:
1、入口是两个开始按钮的监听事件方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | //选择图片所在目录 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、图像处理的核心代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 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,就达到了这样的效果。当然,不是每张图片都是这样修改,有些图片可能修改尺寸,而不修改图片质量更好。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?