想要实现利用Android Studio实现Png图片压缩功能需要做很多调研,特别是像我这种只擅长java的开发者,需要调研的东西更多。下面的学习部分会大致列出需要的知识和技术积累。
一、学习
学习一:android gradle 打印日志
println “需要打印的日志” 然后在Gradle 方法名 就可以查看打印的内容
学习二:参考生成jar包的任务
task makeJar(type: Copy) {
//删除存在的jar包,这里打包jar包名字是MyUtils.jar
delete 'build/libs/MobileAssistant.jar'
//设置拷贝的文件 from路径下的文件into到build/libs/路径下,方便找到
from('build/intermediates/packaged-classes/debug/')
//打进jar包后的文件目录
into('build/libs/')
//将classes.jar放入build/libs/目录下
//include ,exclude参数来设置过滤
//(我们只关心classes.jar这个文件)
include('classes.jar')
//重命名
rename('classes.jar', 'MobileAssistant.jar')
}
学习三:gradle 执行命令行方式一
println "git --version".execute() // "命令".execute()可执行命令行的命令
println "git --version".execute().text.trim() // 末尾添加 .text.trim()可获取到命令执行结果
学习四:gradle 执行命令行方式二
def testCmd() {
def out = new ByteArrayOutputStream()
exec {
println "${projectDir}" //D:\Users\able\AndroidStudioProjects\MyGradle2\app
workingDir "${projectDir}"
println System.getProperty('os.name') //Windows 10
if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows')) {
//commandLine 'cmd', '/c', 'git --version' //git version 2.20.1.windows.1
//上面commandLine = executable + args
executable 'cmd'
args '/c', 'java -version'
//java version "1.8.0_131"
//Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
//Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
} else {
commandLine 'sh', '-c', 'git --version'
}
//修改命令输出的地方,默认为控制台
standardOutput = out
}
println out //git version 2.20.1.windows.1
}
testCmd()
学习五:语音和编程功底
Groovy+java+ Gradle+图片压缩
二、效果
通过以上的学习,就能大致实现对工程下所有的图片进行压缩的了。首先看看我的压缩Log吧:
Groovy+java+ Gradle+图片压缩> Configure project :app
-------------------------pngCompress开始启动--------------------------------
脚本位置:/Users/tal/Desktop/test/PngCompress/app
输入文件大小:2060 输出文件大小:1939 图片的压缩了:5%
输入文件大小:2783 输出文件大小:2326 图片的压缩了:16%
输入文件大小:2963 输出文件大小:2378 图片的压缩了:19%
输入文件大小:4905 输出文件大小:3279 图片的压缩了:33%
输入文件大小:9128 输出文件大小:4959 图片的压缩了:45%
输入文件大小:15132 输出文件大小:7619 图片的压缩了:49%
输入文件大小:17769 输出文件大小:7420 图片的压缩了:58%
输入文件大小:6387 输出文件大小:3837 图片的压缩了:39%
输入文件大小:10413 输出文件大小:5527 图片的压缩了:46%
输入文件大小:4490 输出文件大小:3086 图片的压缩了:31%
输入文件大小:6895 输出文件大小:3980 图片的压缩了:42%
输入文件大小:5045 输出文件大小:2873 图片的压缩了:43%
输入文件大小:2302 输出文件大小:1895 图片的压缩了:17%
输入文件大小:2958 输出文件大小:2020 图片的压缩了:31%
-------------------------pngCompress运行完成--------------------------------
----------------------------------------------------------------------------
原图片大小:93230 压缩后图片大小:53138 总体减少比例:43%
----------------------------------------------------------------------------
BUILD SUCCESSFUL in 1s
(base) bogon:PngCompress tal$
就尽情的夸我吧,这个格式已经很漂亮了。但是除了上面的完美日志之外还有本地持久化的信息,详情见下图:
image.png
1、lib_png和app:是跟工程拥有一样结构的图片资源路径-仅仅只有图片。
2、RecordList:是所有需要压缩的原始图片列表:
3、RecordDetail :是压缩图片的压缩比+输入路径+输出路径的列表
image.png
为什么要有RecordList和RecordDetail?
答疑:
1、RecordList:我是想用RecordList过滤下,已经压缩过的图片不需要去重复压缩。
2、RecordDetail:检查压缩的图片是不是失真了,要是有问题就不能替换成压缩后的图片。
三、代码
// 递归获取某目录下的所有子目录以及子文件
List<String> getAllFilePaths(String filePath, List<String> filePathList) {
File[] files = new File(filePath).listFiles()
if (files == null) {
return filePathList
}
for (File file : files) {
if (file.isDirectory()) {
// filePathList.add(file.getPath() + " <------------这是文件夹")
filePathList.add(file.getPath())
getAllFilePaths(file.getAbsolutePath(), filePathList)
} else {
filePathList.add(file.getPath())
}
}
return filePathList
}
def getAllFilePath() {
println "cd ..".execute().text.trim()
def projectPath = "pwd".execute().text.trim()
// println("功能目录:" + projectPath)
List<String> filePaths = new ArrayList<>()
filePaths = getAllFilePaths(projectPath, filePaths)
// for (String path : filePaths) {
// System.out.println(path)
// println("递归获取路径:" + path)
// }
return filePaths
}
def isJustPng(String path) {
if (path == null || path.size() == 0) {
return false
}
if (path.endsWith(".png") && !path.contains(".9")) {
return true
}
return false
}
def getAvailableFileList(List<String> allFileList) {
List<String> tempList = new ArrayList<>()
if (allFileList == null || allFileList.size() == 0)
return
for (String path : allFileList) {
if (isJustPng(path))
tempList.add(path)
}
return tempList
}
def writeToFile(String filePaht, String content) {
try {
// String content = "a dog will be write in file";
// File file = new File("test_appendfile2.txt");
File file = new File(filePaht)
if (!file.exists()) {
file.createNewFile()
}
FileWriter fileWriter = new FileWriter(file.getAbsoluteFile(),true)
BufferedWriter bw = new BufferedWriter(fileWriter)
bw.write(content)
bw.close()
// System.out.println("finish")
} catch (IOException e) {
e.printStackTrace()
}
}
def writeRecordDetail(destFileDir, srcPath, destPath, per) {
def filePath=destFileDir+"/RecordDetail.txt"
def projectPath = "pwd".execute().text.trim()
def tempSrc=((String)srcPath).substring(projectPath.length()+1)
def tempDest=((String)destPath).substring(((String)destFileDir).length()+1)
String content="压缩:"+per+"% "+tempSrc+" ---> "+tempDest+" "+"\n"
writeToFile(filePath,content)
}
def writeRecordList(destFileDir, srcPath) {
def projectPath = "pwd".execute().text.trim()
def filePath=destFileDir+"/RecordList.txt"
def tempSrc=((String)srcPath).substring(projectPath.length()+1)
writeToFile(filePath,tempSrc+"\n")
}
def compress(String destFileDir, String srcPath, String destPath) {
File tempFile = new File(destPath)
if (tempFile.exists()) {
tempFile.delete()
}
def dir = tempFile.getParent()
// println("文件夹路径:" + dir)
if (!new File(dir).exists()) {
new File(dir).mkdirs()
}
def projectPath = "pwd".execute().text.trim()
String cmd = projectPath + "/pngcompress/pngcompress --force --skip-if-larger " + srcPath + " --output " + destPath
print(cmd.execute().text.trim())
//获取文件的大小,计算文件压缩的比例是多少
File inputFile = new File(srcPath)
def intpuLength = inputFile.length()
File outFile = new File(destPath)
def outLength = outFile.length()
def percent = (intpuLength - outLength) / intpuLength
def per = (int) (percent * 100)
println "输入文件大小:" + intpuLength + " 输出文件大小:" + outLength + " 图片的压缩了:" + per + "%"
writeRecordDetail(destFileDir, srcPath, destPath, per)
writeRecordList(destFileDir, srcPath)
}
def getDestPath(String destPath, String path) {
def projectPath = "pwd".execute().text.trim()
String tempStr = path.substring(((String) projectPath).length())
return destPath + tempStr
}
def getFileLength(String path) {
File file = new File(path)
return file.length()
}
def getSrcFileLenght(List<String> srcList) {
if (srcList == null || srcList.size() == 0)
return 0
def total = 0
for (String path : srcList) {
total += getFileLength(path)
}
return total
}
def getReducePercent(long srcTotal, long destTotal) {
def percent = (srcTotal - destTotal) / srcTotal
def per = (int) (percent * 100)
return per + "%"
}
//----------------------------入口函数---------------------------------------
task pngCompress(type: Copy) {
def destPath = "/Users/tal/Desktop/mypng"
println("-------------------------pngCompress开始启动--------------------------------")
println "脚本位置:"+"${projectDir}"
def allFileList = getAllFilePath()
def availableFileList = getAvailableFileList(allFileList)
def srcTotalLenght = getSrcFileLenght(availableFileList)
def destTotalLenght = 0
for (String path : availableFileList) {
String getDestPath = getDestPath(destPath, path)
destTotalLenght += getFileLength(getDestPath)
compress(destPath, path, getDestPath)
}
println("-------------------------pngCompress运行完成--------------------------------")
println ""
println "----------------------------------------------------------------------------"
println("原图片大小:" + srcTotalLenght + " 压缩后图片大小:" + destTotalLenght + " 总体减少比例:" + getReducePercent(srcTotalLenght, destTotalLenght))
println "----------------------------------------------------------------------------"
println ""
}
执行方式:
gradle pngCompress
网友评论