最近公司有个批量压缩图片的任务交给我。
对于IO的是操作,我不是很擅长,自己比较shui 。不管怎么样,经过的不懈的努力,今天终于完成了。
所以打算分享一下。
任务要求:
给你一个文件夹,把该文件夹下的所有.png文件进行压缩,然后保存到相对文件夹的镜像对应子文件夹目录下,
并支持SVN版本的更替的增量压缩(即:修改或新增的图片才压缩)
解决方案:
网上有很多压缩的方式,也很繁杂,我也尝试过很多,其中对tinifypng.com网址的压缩还是比较满意的。
网址:https://tinypng.com/
操作:直接把想压缩的图片拖上去就可以了。(当然你不嫌麻烦话)
如果做批量上传处理和下载,就是本次任务的意义了。
实现过程: 按照 https://tinypng.com/developers/reference/dotnet 网站提供的API reference (这里我用的是.Net的API)
1. 首先 添加 NuGet package. (项目右键 管理NuGet程序包) 搜索tinify 下载安装 即可调用
2.去网站上注册申请Key(每个key每月可免费压缩500张图)
3.压缩过程采用异步形式,其他的一些图片的压缩格式,裁剪等参看官网说明 。
4.可以 Tinify.CompressionCount 知道你当月剩余可压缩次数
如果你有很多图片可以购买会员提高次数,也可以多注册一个帐号,轮询使用。
下面是关键代码
做一个递归查找文件夹下的图片,递归处理上传压缩
public static void RecursiveFolder(DirectoryInfo theFolder, DirectoryInfo outFolder, string outPath)
{
if (theFolder == null)
return;
DirectoryInfo[] dirInfo = theFolder.GetDirectories();
if (dirInfo.Length > 0)
{
foreach (var dir in dirInfo)
{
if (!dir.Name.ToLower().EndsWith("svn"))
{
var th = outFolder.CreateSubdirectory(dir.Name);
RecursiveFolder(dir, th, outPath + "\\" + dir.Name);
}
}
}
foreach (FileInfo file in theFolder.GetFiles("*.png"))
{
sub.GetWCInfo(file.FullName, true, true);
if (sub.IsSvnItem)
{
string version;
if (fileRevisionDict.TryGetValue(file.FullName, out version))
{
if (!version.Equals(sub.Revision.ToString()))
{
fileRevisionDict[file.FullName] = sub.Revision.ToString();
Console.WriteLine("RecursiveFolder " + file.FullName + " version " + sub.Revision + " != " + version + " Request the compression");
Solve(file.FullName, outPath + "\\" + file.Name);
}
else
{
Console.WriteLine("RecursiveFolder " + file.FullName + " version " + sub.Revision + " == " + version);
}
}
else
{
fileRevisionDict.Add(file.FullName, sub.Revision.ToString());
Console.WriteLine("RecursiveFolder " + file.FullName + " version " + sub.Revision + " (new)Request the compression");
Solve(file.FullName, outPath + "\\" + file.Name);
}
}
else
{
Console.WriteLine("RecursiveFolder not versioned");
}
}
}
核心代码二: (压缩处理)
public static async void Solve(string fileFullName, string outFile)
{
try
{
var expiredKey = tinifyKeysArray[expiredKeysCnt];
Tinify.Key = expiredKey;
if (expiredKeysCnt > tinifyKeysArray.Count)
{
Console.WriteLine("Solve All key times are used up this month.");
Console.WriteLine("Solve Welcome back next month.");
return;
}
try
{
Console.WriteLine("Solve Try: {0} ", fileFullName);
var source = Tinify.FromFile(fileFullName);
sumUploadCnt++;
Console.WriteLine(" ----------------- await : start ----------------- {0}", sumUploadCnt);
var copyrighted = source.Preserve("copyright", "creation");
await copyrighted.ToFile(outFile);
sumDownloadCnt++;
Console.WriteLine(" ----------------- await : end ----------------- {0}", sumDownloadCnt);
if (sumDownloadCnt == sumUploadCnt)
{
var compressionsThisMonth = Tinify.CompressionCount;
if (compressionsThisMonth >= thisMonthCnt)
{
expiredKeysCnt++;
}
Console.WriteLine("Solve This key has been compressed {0} times, remaining {1} times this month.",
compressionsThisMonth, thisMonthCnt - compressionsThisMonth);
Console.WriteLine("Solve The task finished, Welcome to use again.");
}
}
catch (AccountException e)
{
Console.WriteLine("Solve The AccountException error message is: " + e.Message);
expiredKeysCnt++; //use next key
Solve(fileFullName, outFile);
}
catch (ClientException e)
{
Console.WriteLine("Solve The ClientException error message is: " + e.Message);
}
catch (ServerException e)
{
Console.WriteLine("Solve The ServerException error message is: " + e.Message);
}
catch (ConnectionException e)
{
Console.WriteLine("Solve The ConnectionException error message is: " + e.Message);
}
catch (System.Exception e)
{
Console.WriteLine("Solve The System.Exception error message is: " + e.Message);
}
}
catch (System.Exception e)
{
Console.WriteLine("Solve Validation of API key failed : " + e.Message);
tinifyKeysArray.RemoveAt(expiredKeysCnt);
Solve(fileFullName, outFile);
}
}
其中 tinifyKeysArray 是个Key池
private static List tinifyKeysArray = new List()
{
"你的Key1"
};
其他就是一个SNV版本号的读取
sub.GetWCInfo();
添加SubWCRevCom.exe引用,
using TinifyAPI;
using LibSubWCRev;
即可使用。
至于读写版本控制文件就不详述了,可以按照自己喜欢的格式写,就是注意一下目录中文的话,可能会乱码问题,so 压缩路径和导出路径最好都是全英文的,包括版本控制路径
最后写一个bat脚本以后就可以双击运行了。很方便
@echo off
c:
cd \batch\Debug
TinifyPng F:\SVN\blackjack\doc\minister C:\Users\Administrator\Desktop\temp\dest C:\batch\TinifyPng.txt
简单解释下:
首先进入C盘\batch\Debug 目录,(上面程序运行后生成的Debug目录的备份目录)
Tinify 需要压缩文件的总目录路径 导出文件的目录路径 版本记录文件的路径
有兴趣的同学可以和我讨论,留言。
注:我的代码之后会更新在Github上,小工具也会上传,小工具做了限制,只能是有SVN版本号的才会压缩。
小工具:http://download.csdn.net/download/u010579068/10262653