脚本说明
使用C#编写的图片压缩程序。读取指定目录下的图片文件,使用无损压缩算法将图片压缩备份指定目标目录中。
程序首先会提示用户输入需要压缩的目录地址和压缩后的目标地址。然后通过递归的方式获取目录下的所有图片文件路径。对于每个图片文件,程序会调用CompressImage
方法进行压缩处理。
CompressImage
方法中,程序会根据需要压缩的大小和压缩质量参数来压缩图片。如果第一次调用,并且原始图片的大小小于要压缩的大小,程序会直接复制文件并返回true。否则,程序会按比例缩放图片,并创建一个新的Bitmap对象来绘制缩放后的图片。然后,根据指定的压缩质量参数,将图片压缩备份到另外一个目录。并保持原来目录结构。
最后,程序将错误信息(压缩失败的文件路径)写入到目标地址下的Error.txt文件中。
使用方法
1.找到需要进行压缩备份的图片资源路径。
2.程序运行起来后,输入源路径与目标路径。
3.程序就跑起来啦!等待程序运行结束,生成error.txt是异常处理的文件项。
代码分享(C#)
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Soian.CompressImage
{
internal class Program
{
static List<string> errorLines = new List<string>();
static void Main(string[] args)
{
//string beforPath = @"E:\img\befor";
//string afterPath = @"E:\img\after";
Console.WriteLine("输入需要压缩的目录地址:");
string beforPath = Console.ReadLine();
Console.WriteLine("输入压缩后的目标地址:");
string afterPath = Console.ReadLine();
var images = Directory.GetFiles(beforPath, ".", SearchOption.AllDirectories).Where(s => s.EndsWith(".png") || s.EndsWith(".jpg"));
foreach (var imgpath in images)
{
string compresspath = imgpath.Replace(beforPath, afterPath);
// 读取原图片 压缩 到新的位置
if (CompressImage(imgpath, compresspath))
{
Console.WriteLine(imgpath);
}
else
{
Console.WriteLine(imgpath+"--error");
errorLines.Add(imgpath);
}
}
// 错误信息输出到目录下Error.txt
System.IO.File.WriteAllLines(afterPath + @"\Error.txt", errorLines.ToArray());
}
/// <summary>
/// 无损压缩图片
/// </summary>
/// <param name="sFile">原图片地址</param>
/// <param name="dFile">压缩后保存图片地址</param>
/// <param name="flag">压缩质量(数字越小压缩率越高)1-100</param>
/// <param name="size">压缩后图片的最大大小</param>
/// <param name="sfsc">是否是第一次调用</param>
/// <returns></returns>
public static bool CompressImage(string sFile, string dFile, int flag =98, int size = 800, bool sfsc = true)
{
//目录是否创建,为保存做准备
string dFileFolder = dFile.Substring(0, dFile.LastIndexOf('\\'));
if (!Directory.Exists(dFileFolder))
{
Directory.CreateDirectory(dFileFolder);
}
//如果是第一次调用,原始图像的大小小于要压缩的大小,则直接复制文件,并且返回true
FileInfo firstFileInfo = new FileInfo(sFile);
if (sfsc == true && firstFileInfo.Length < size * 1024)
{
firstFileInfo.CopyTo(dFile);
return true;
}
Image iSource = Image.FromFile(sFile);
ImageFormat tFormat = iSource.RawFormat;
int dHeight = iSource.Height / 2;
int dWidth = iSource.Width / 2;
int sW = 0, sH = 0;
#region 按比例缩放
Size tem_size = new Size(iSource.Width, iSource.Height);
if (tem_size.Width > dHeight || tem_size.Width > dWidth)
{
if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth))
{
sW = dWidth;
sH = (dWidth * tem_size.Height) / tem_size.Width;
}
else
{
sH = dHeight;
sW = (tem_size.Width * dHeight) / tem_size.Height;
}
}
else
{
sW = tem_size.Width;
sH = tem_size.Height;
}
#endregion
Bitmap ob = new Bitmap(dWidth, dHeight);
Graphics g = Graphics.FromImage(ob);
g.Clear(Color.WhiteSmoke);
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(iSource, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);
g.Dispose();
#region 压缩质量处理
EncoderParameters ep = new EncoderParameters();
long[] qy = new long[1];
qy[0] = flag;//设置压缩的比例1-100
EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
ep.Param[0] = eParam;
#endregion
try
{
ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpegICIinfo = null;
for (int x = 0; x < arrayICI.Length; x++)
{
if (arrayICI[x].FormatDescription.Equals("JPEG"))
{
jpegICIinfo = arrayICI[x];
break;
}
}
if (jpegICIinfo != null)
{
ob.Save(dFile, jpegICIinfo, ep);//dFile是压缩后的新路径
FileInfo fi = new FileInfo(dFile);
if (fi.Length > 1024 * size)
{
flag = flag - 10;
CompressImage(sFile, dFile, flag, size, false);
}
}
else
{
ob.Save(dFile, tFormat);
}
return true;
}
catch
{
return false;
}
finally
{
iSource.Dispose();
ob.Dispose();
}
}
}
}