C#编写缩小jpg格式文件大小的工具

1 篇文章 0 订阅
本文介绍了一种针对网站加载慢问题的解决方案,通过编写C# Console应用程序批量缩小jpg图片文件大小,从而减少加载时间。程序提供命令行参数支持,包括设置压缩质量、是否覆盖原文件、备份原文件和搜索子目录。通过调整图片质量,可以在几乎不牺牲视觉效果的情况下显著减小文件尺寸。
摘要由CSDN通过智能技术生成

有一天,客户领导说网站加载慢

客户的网站请广告公司设计的,堆叠了大量的高精度美图。忽然有一天,老总说网站怎么这么慢?

客户不懂技术,只管提需求

网站在建立的时候就已经告知会有什么优点和弱项了,但是客户都是善于遗忘的人。他们只管现在,不管过去。所以唯一不必的是变化这句话就又被验证了一次。
怎么办呢?

  1. 全新的界面设计 ,重构网站?显然不太现实,刚做好没两个月。
  2. 缩小图片文件大小是唯一可行可试的方案。第一步缩小时将png全部改为了jpg,因为不用考虑透明度的问题。第二步就是降低jpg图片的质量,随之减小文件大小。
    tinypng.com 做了几张,感觉太麻烦了,这要做到几时去呢?
    于是自己写了一个小工具,可以批量的缩小jpg文件的大小,当然图片质量会略有下降了,但是普通访问者都几乎无法注意到,是可以接受的。

为了方便,写了一个Console应用,命令行方式运行:
Please enter resize argument.
Usage: JpgResizer -r 75 -o -b
Usage: JpgResizer *.jpg -r 75 -o -b -s
-b : 备份原始文件,在覆盖模式时有用 backup the original file. use when -o is set.
-o : 覆盖模式,直接重写原文件 overwrite the original file.
-s : 搜索当前目录下的所有子目录下的文件 search all jpg files in sub-directories. ignore filename.
-r : 压缩后图片质量级别 compress level. default is 75, 100 is best.
在这里插入图片描述

源代码,复制可用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace JpgResizer
{
    class Program
    {
        static bool isOverwrite = false;
        static Int64 ratio = 75L;
        static bool isIncludeSubDirectories = false;
        static bool isBackup = false;

        static void Main(string[] args)
        {
            
            string filename = "*.jpg";

            if (args.Length == 0)
            {
                Console.WriteLine("============== JPG Compress tool ==================");
                Console.WriteLine("= Author : shrek");
                Console.WriteLine("= Contact: (QQ390652)");
                Console.WriteLine("= Date   : 2021.01.21");
                Console.WriteLine("= Hangzhou Codans Cyberinfo Company. ");
                Console.WriteLine("===================================================");
                Console.WriteLine("Please enter resize argument.");
                Console.WriteLine("Usage: JpgResizer <filename> -r 75 -o -b");
                Console.WriteLine("Usage: JpgResizer *.jpg -r 75 -o -b -s");
                Console.WriteLine(" -b  : backup the original file. use when -o is set.");
                Console.WriteLine(" -o  : overwrite the original file. ");
                Console.WriteLine(" -s  : search all jpg files in sub-directories. ignore filename.");
                Console.WriteLine(" -r  : compress level. default is 75, 100 is best.");

                return;
            }

            filename = args[0];
            if (!filename.Contains(".jpg") && !filename.Contains(".jpeg") && !filename.Contains("*"))
            {
                Console.WriteLine("   missing filename.");
                return;
            }

            var index = 1;
            foreach (var item in args.Skip(1))
            {
                if (item.ToLower() == "-o")
                {
                    isOverwrite = true;
                }
                if (item.ToLower() == "-b")
                {
                    isBackup = true;
                }
                else if (item.ToLower()== "-s")
                {
                    isIncludeSubDirectories = true;
                }
                else if (item.ToLower()=="-r")
                {
                    if (args.Length >= index+1)
                    {
                        ratio = Int64.Parse(args[index + 1]);
                    }
                    else
                    {
                        Console.WriteLine("  missing ratio paramenter.");
                        return;
                    }
                }
                index++;
            }

            if (isIncludeSubDirectories)
            {
                ListJpg(AppContext.BaseDirectory);
            }
            else { 
                VaryQualityLevel(filename, ratio, isOverwrite);
            }

        }

        private static void ListJpg(string dir)
        {
            DirectoryInfo d = new DirectoryInfo(dir);
            FileInfo[] files = d.GetFiles("*.jpg");//文件
            DirectoryInfo[] directs = d.GetDirectories();//文件夹
            foreach (FileInfo f in files)
            {
                VaryQualityLevel(f.FullName, ratio, isOverwrite);  
            }
            //获取子文件夹内的文件列表,递归遍历  
            foreach (DirectoryInfo dd in directs)
            {
                ListJpg(dd.FullName);
            }
        }

        private static ImageCodecInfo GetEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }

        private static void VaryQualityLevel(string fileName,Int64 ratio,bool isOverwrite)
        {
            Console.WriteLine($"filename : {fileName}");
            // Get a bitmap. The using statement ensures objects  
            // are automatically disposed from memory after use.  
            var originalSize = new FileInfo(fileName).Length;
            var newSize = 0L;


            var newFileName = Path.GetFileNameWithoutExtension(fileName) + "_new" + Path.GetExtension(fileName);
            if (isOverwrite)
            {
                newFileName = fileName;
                if (isBackup)
                {
                    var backupFileName = Path.GetFileNameWithoutExtension(fileName) + "_original" + Path.GetExtension(fileName);
                    File.Copy(fileName, backupFileName, true);
                }
            }
            using (Bitmap bmp0 = new Bitmap(fileName))
            {
                var bmp1 = new Bitmap(bmp0);
                bmp0.Dispose();
                ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);

                // Create an Encoder object based on the GUID  
                // for the Quality parameter category.  
                System.Drawing.Imaging.Encoder myEncoder =
                    System.Drawing.Imaging.Encoder.Quality;

                // Create an EncoderParameters object.  
                // An EncoderParameters object has an array of EncoderParameter  
                // objects. In this case, there is only one  
                // EncoderParameter object in the array.  
                EncoderParameters myEncoderParameters = new EncoderParameters(1);

                EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, ratio);
                myEncoderParameters.Param[0] = myEncoderParameter;
                bmp1.Save(newFileName, jpgEncoder, myEncoderParameters);
                newSize = new FileInfo(newFileName).Length;
                Console.WriteLine($"  resize ok. {originalSize} -> {newSize} { ((originalSize - newSize) * 100 / originalSize).ToString("0.#") }% compressed.");
            }
        }
    }
}

总结

参考了以下信息,站在别人的肩膀上就看得远一些。

【日月谈】是自己维护的一个微信小程序,可以在线写日记,有好多朋友写了快20年,您如果有兴趣,可以去用用看。
https://everyday.yuelvsu.com

#github https://github.com/ihugang/JpgResizer #
[1]: https://docs.microsoft.com/en-us/dotnet/desktop/winforms/advanced/how-to-set-jpeg-compression-level?view=netframeworkdesktop-4.8&redirectedfrom=MSDN

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值