多重图片优化Cli工具 | Android跨界py之旅

1,964 阅读7分钟

先贴下我的工具人项目地址 github.com/Leifzhang/T…

吹牛

今天给各位大佬水一篇文章,内容可能会对你有一些实际帮助,也有可能一点都没有,这算是年前最后一吹了吧。今天的主题就是我们吹一吹pythonshell

一个安卓开发不应该需要执着于语言,前一阵子鸿洋大佬分享了一篇别人关于图片优化的文章,我2020年初在哈啰的时候也做过类似的,但是我做的更奇怪一点,我选择的方式是通过cli(命令行界面)的方式去实现的。

这个还是受我之前的大哥启发的,由于当时要将App完成繁体版本的开发,而且之前由于代码不规范的问题,很多中文字符都是写在java代码中的,这样整个项目的国际化的难度就是指数型上升了。

当时我感觉这个需求不是特别好做(太难了)。为了这个需求我大哥偷偷干了啥呢?大哥写了个sh命令行工具,之后通过python逐行读取java xml文件,因为中文字符符合\u4e00-\u9fa5 (中文),那么只要当前行能匹配上对应规则,之后进行后续的文本提取操作。

当然后面我大哥的命令行工具还是在持续演化,我也给其中贡献了一部分辣鸡代码,但是大哥的思路还是对我有很大的启发。一个开发其实不应该拘泥于你当前属性的代码,能更方便更简单的解决重构的痛点,这样才是最好的。

正文

我们先聊聊技术选型,毕竟还是要先把方案都确定好,然后才能愉快的开发(吹牛逼)。

Png压缩

PNG图片压缩,首先想的的是tinypng,但是一个tinypng是网站,但是他也提供接口调用,但是调用对方接口需要收费,留下了贫穷的眼泪。

之后调研到pngquantpngquant可以由命令行执行,同时压缩比例也是在70%左右,同时配合python的情况下可以对我们的项目做很好的支持效果。有兴趣了解图片压缩相关的可以看下另外一个大佬以前的分析PNG 图片压缩对比分析

确认了方案,我们只要用python直接调用shell命令行,去处理当前的文件就可以了。

// 最后跟上文件路径就行了
pngquant -f --skip-if-larger --strip --ext=.png --quality 70-70  

基本只要执行上面的命令就可以完成一张png图片的压缩了,而压缩比例当前选择的是70。

无Alpha Png转JPG

Jpg相比于Png,压缩比例会更高但是有个小缺点,就是不支持透明的图片,所以当项目中如果存在没有Alpha的Png,我们可以直接将他们转化成Jpg。

Python图像库PIL(Python Image Library)是python的第三方图像处理库,但是由于其强大的功能与众多的使用人数,几乎已经被认为是python官方图像处理库了。其官方主页为:PIL。 PIL历史悠久,原来是只支持python2.x的版本的,后来出现了移植到python3的库pillow,pillow号称是friendly fork for PIL,其功能和PIL差不多,但是支持python3。

Python的PIL图像库堪称强大无比,但是唯独的烦恼就是先要pip安装下对应的依赖,对于开发略微有点要求。

这部分其实就和安卓获取Bitmap之后其实一样,PIL获取的Image之后,同样可以获取到当前图像的ARGB像素,我们只要根据A的值是否大于0去做判断就行了。

def changeImage(file,outPath):
	filePath = file
	png = Image.open(filePath).convert('RGBA')
	alpha_index = png.getbands().index('A')
	if alpha_index < 0 :
		bg = Image.new('RGB', size = png.size, color = (255, 255, 255))
		bg.paste(png,png)
		bg.save(outPath)
		print(outPath)
		return alpha_index
	return alpha_index

这部分代码包含了检查图像以及将Png保存成jpg的操作。其中png.getbands().index('A')表示判断图片内Alpha值的数量。

cwebp

webp是Google推出的一种新式图片格式、相比于常用的jpg、png和gif格式,最大的优势就是同等质量下压缩率更高、图片文件更小、利于节约存储空间和网络带宽。更多信息可以查看官网(需要自备梯子):developers.google.com/speed/webp/… Google官方推出了工具cwebp用于进行其他图片格式与webp格式进行相互转换

这里有个小贴士,并不是所有的的png图片转化成webp都会变小,有些纯色的图片用webp转化之后反倒会变大。

所以webp图片的转化其实只要使用谷歌官方的方案就行了。同样我们也是采用shell命令行的方式。

// 后面跟上文件路径就行了
cwebp -q 75 {} -o {}.webp -quiet

当前压缩比例统一为75,同时静默压缩。

cli开发

上面只是介绍了下技术选型相关的,但是只是有了这些其实和你真的写出来还是有差距的。我们理顺下整体逻辑,看下一个命令工具都干了些什么。

  1. 获取当前文件路径,遍历出文件夹内的图片
  2. 获取原文件大小,同时进行上述图片压缩操作,temp文件,比较前后差异,如果变大了则不处理
  3. 最后选择覆盖原文件并删除temp
  4. 最后输出压缩大小

顺便说一下,我的python超菜的,如果有什么写错的地方,反正也不是不能用吗。

# 获取指定路径下所有指定后缀的文件
def GetFileFromThisRootDir(dir, ext=None):
    allfiles = []
    needExtFilter = (ext != None)
    for root, dirs, files in os.walk(dir):
        for filespath in files:
            filepath = os.path.join(root, filespath)
            #if not ignorePath.__contains__(filepath):
            #print  filepath
            text = os.path.splitext(filepath)[0][1:]
            isIgnore = 0
            for ignoreText in ignorePath:
                if text.find(ignoreText)>=0:
                    isIgnore+= 1
            if isIgnore > 0:
                continue
            if text.find('.9')>=0:
                continue
            extension = os.path.splitext(filepath)[1][1:]
            fileName = os.path.basename(filepath)
            fileName = fileName.split('.')[0]
            if needExtFilter and extension in ext:
                print fileName
                if needExtFilter and fileName not in ignoreFileName :
                    allfiles.append(filepath)
    return allfiles

上面的代码是获取到当前的文件夹路径,然后剔除我们所不需要的一部分文件夹,之后返回整个文件列表。

然后我们就可以把这个文件列表,通过上面的三种不同的方式,进行后续的图片压缩的加工操作了。

优化一下

虽然看起来我们的py是已经可以用了,但是因为依托于很多命令行工具,所以如果万一你的队友没有装这些东西,你装逼就崩啊。

所以我们要在这方面进行一定的增强,在大部分电脑都是mac的情况下,我们需要大佬们先要有homebrew, 如果这都没装,那么可以看下这个www.jianshu.com/p/7071c1419…

checkCmd = "which pngquant"
   result = os.system(checkCmd)
   if result != 0:
       cmd = "brew install pngquant"

之后以pngquant为例,我们可以通过which pngquant命令行,判断当前设备是否安装了对应的命令行工具,如果没有则帮助开发人员安装下。这样既能避免掉一些没安装的状况,同时也能优化下我们的cli的体验。

另外我们可以把我们的命令行工具copy的bin目录下,这样就可以直接在命令行内使用工具人了,有兴趣的可以参考下install的sh。

另外我抄袭了下我之前老大的命令行的辣鸡UI,使用者可以通过输入来决定当前使用的是哪个命令。

export LANG=en_US.UTF-8
INSTALL_PATH=`cd ~;pwd`/.toolman/kit
CONFIG_PATH=`cd ~;pwd`/.toolman_config

# 清屏
clear

function echo_help () {
	echo "***********************mbull帮助**********************"
	echo "1、[u|update]			更新Kit"
	echo "2、[png|pngquant]		使用 pngquant 进行png格式的压缩"
	echo "3、[m|monkey]			Android Monkey测试"
	echo "4、[w|webP]			使用 cwebp 进行png格式webP的转化"
	echo "5、[j|jpg]				使用 py 进行png格式jpg的转化"
	echo "*****************************************************"
}

// 获取输入指令  然后根据字符串匹配执行对应的sh
action=$1
if [[ -z "$action" ]]; then
	echo_help
	read -p '指定一个操作:' action
	if [[ -z "$action" ]]; then
		echo "ERROR: action is not valid.";
		exit 1;
	fi
fi

if [ $action == "update" ]||[ $action == "u" ]; then
	sh $INSTALL_PATH/bin/kitupdate.sh
elif [ $action == "png" ]||[ $action == "pngquant" ]; then
	sh $INSTALL_PATH/bin/pngquant.sh $2
elif [ $action == "monkey" ]||[ $action == "m" ]; then
	sh $INSTALL_PATH/bin/monkey.sh $*
elif [ $action == "webp" ]||[ $action == "w" ]; then
	sh $INSTALL_PATH/bin/pngToWebp.sh $*
elif [ $action == "jpg" ]||[ $action == "j" ]; then
	sh $INSTALL_PATH/bin/pngToJpg.sh $*
else
	echo "ERROR: Currently supported actions: "
	echo_help 
fi

下面进入看图说话模式

image.png

看下之前压缩的效果如何吧。 image.png

TODO

我本来打算把脚手架的功能也整合到我的工具人组件内的,奈何最近太懒了,啥都不想淦然后吧就搁置了。但是的确工具人python能帮助我们做很多有意思的项目优化。

总结

一个安卓开发其实可以借助更多工具去辅助自己更好的去完成项目的优化,不需要拘泥于java。不妨试试跨界一下,可能会有意想不到的收获呢。