Apk瘦身脚本 - 图片批量压缩

本文介绍了一个Python脚本,用于在AndroidStudio项目中自动检测并压缩大尺寸的PNG图片为WebP格式,同时提供了一种方法来控制压缩策略。脚本通过遍历项目文件夹,对符合条件的图片进行转换和压缩,以减少包体积。

有时项目开发到一定程度就会发现,项目中充斥着各种png大图资源,导致包体积越来越大,想要借助AndroidStudio自带的png转webp工具进行压缩转换,又只能一张一张地转,看着那几十张图,真是头都大。这时候就想着,要是能让机器帮我操作就好了。。。

好的,这就奉上!

这个脚本实现起来比较简单,主要是

  1. 检索项目中大png图片然后转换成webp
  2. 将大的webp也压缩成小的webp

详情请看代码

import fnmatch
import os
import shutil

from PIL import Image

CWD = os.getcwd()

tmp_path = CWD + os.sep + 'temp'


def file_split(split_url):
    (parent_path, file_name) = os.path.split(split_url)
    (shot_name, extension) = os.path.splitext(file_name)
    return parent_path, file_name, shot_name, extension


def match_patterns(_file, _patterns):
    for _pattern in _patterns:
        if fnmatch.fnmatch(_file, _pattern):
            return True
    return False


def convert_webp_to_png(webp_file, png_file):
    with Image.open(webp_file) as img:
        img.convert('RGBA').save(png_file, 'PNG')


def convert_png_to_webp(png_file, webp_file, quality=85):
    with Image.open(png_file) as img:
        img.save(webp_file, 'WEBP', quality=quality)


def compress_webp_files(directory, size, quality=85):
    print(f"⭐ " * 50)
    print(f"Get ready to compress, please fasten your seat belts")
    print(f"Current working directory is: {directory}")
    print(f"Below is the compressed file")
    print(f"👇" * 50)
    if os.path.exists(tmp_path):
        shutil.rmtree(tmp_path)
    os.mkdir(tmp_path)
    for root, dirs, files in os.walk(directory):
        if (os.sep + "src" + os.sep) not in root:
            continue
        if (os.sep + "raw") in root:
            continue
        for file in files:
            """
            9 Patch压缩
            手动处理
            
            Webp压缩
            1、先将webp转换到tmp的png
            2、再将tmp的png转换到tmp的webp
            3、比较原webp和tmp的webp大小
            4、有效压缩的,覆盖原webp

            Png压缩
            1、先将png转换到tmp的webp
            2、比较原png和tmp的webp大小
            3、有效压缩的,删除原png并更换为压缩webp
            """
            if not match_patterns(file, force_patterns):
                continue
            if match_patterns(file, ignore_patterns):
                print(f"ignore handle file -> {file}")
                continue
            elif file.lower().endswith('.webp') and os.path.getsize(os.path.join(root, file)) > size:
                ori_webp_path = root + os.sep + file
                png_path = tmp_path + os.sep + file_split(ori_webp_path)[2] + '.png'
                compress_webp_path = tmp_path + os.sep + file_split(ori_webp_path)[2] + '.webp'

                # webp -> png
                convert_webp_to_png(ori_webp_path, png_path)
                # webp <- png
                convert_png_to_webp(png_path, compress_webp_path, quality=quality)

                # 过滤忽略压缩文件比源文件还大的情况
                if os.path.getsize(ori_webp_path) > os.path.getsize(compress_webp_path):
                    shutil.move(compress_webp_path, ori_webp_path)
                    print(f"handle webp: {ori_webp_path}")
                os.remove(png_path)
            elif file.lower().endswith('.png') and os.path.getsize(os.path.join(root, file)) > size:
                png_path = root + os.sep + file
                compress_webp_path = tmp_path + os.sep + file_split(png_path)[2] + '.webp'
                web_path = root + os.sep + file_split(png_path)[2] + '.webp'

                # png -> webp
                convert_png_to_webp(png_path, compress_webp_path, quality=quality)

                # 过滤忽略文件比源文件还大的情况
                if os.path.getsize(png_path) > os.path.getsize(compress_webp_path):
                    shutil.move(compress_webp_path, web_path)
                    os.remove(png_path)
                    print(f"handle png -> {png_path}")
                else:
                    os.remove(compress_webp_path)
                    continue
    # 清空缓存
    shutil.rmtree(tmp_path)


# 忽略压缩哪些文件(ignore_patterns 优先级大于 force_patterns)
ignore_patterns = [
    '*.9.png',
    'video_match_bg.webp',
    'video_match_cycle*.webp',
    'video_match_xdt.webp',
]

# 只压缩哪些文件
force_patterns = [
    'bg_splash.webp',
    'ic_splash_logo.webp',
    'ic_splash_slogon.webp',
]

if __name__ == '__main__':
    # 1、处理20K以上的图,2、以85%的压缩比例进行压缩
    compress_webp_files(directory=CWD, size=20000, quality=85)

食用方式如下(记得要安装好Python环境哈):

python3 compress_img.py

经过使用检验,实际压缩后与原图没多大区别,但谨慎起见,脚本执行完成之后记得检查一下压缩结果哈

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值