Gradle插件:APK打包前如何转换所有图片资源
嘿,这个需求在Android开发里挺实用的,毕竟WebP能大幅减小包体积还不怎么损失画质。我给你整理了三种靠谱的实现方式,从最简单的官方配置到灵活的自定义脚本,你按需选就行~
方法一:用AGP内置功能自动转换(最推荐)
从AGP 4.2版本开始,官方就提供了一键配置自动将PNG/JPG转WebP的功能,完全不用写复杂逻辑,步骤超简单:
- 打开你app模块下的
build.gradle(Groovy)或者build.gradle.kts(Kotlin DSL) - 在
android代码块里加上以下配置:
Groovy版本:
android { // 这里放你已有的配置,比如compileSdk、defaultConfig这些 compileSdk 34 defaultConfig { applicationId "com.your.app" minSdk 21 targetSdk 34 // ... 其他配置 } // 新增的WebP自动转换配置 aaptOptions { // 开启自动转换开关 convertToWebp = true // 设置转换质量,范围0-100,默认85就够用了,追求画质可以调高点 webpQuality = 85 // 是否保留原图片:如果你的App需要兼容Android 4.3(API 18)以下版本,设为true;不需要的话设为false删除原图 webpKeepOriginal = false } }
Kotlin DSL版本:
android { compileSdk = 34 defaultConfig { applicationId = "com.your.app" minSdk = 21 targetSdk = 34 // ... 其他配置 } aaptOptions { convertToWebp = true webpQuality = 85 webpKeepOriginal = false } }
- 同步Gradle之后,下次构建APK的时候,AGP会自动把所有res目录下的PNG/JPG转成WebP,还会自动替换原资源(如果
webpKeepOriginal设为false的话)。
小提醒:透明WebP需要Android 4.3及以上版本支持,要是你的用户里还有更低版本的设备,记得把webpKeepOriginal设为true,这样系统会自动根据设备版本选合适的资源。
方法二:Android Studio内置工具批量转换(适合一次性处理)
如果你只是想把现有图片一次性转成WebP,不想每次构建都折腾,可以用Studio自带的可视化工具:
- 切换到Project视图,找到
app/src/main/res下的drawable或者mipmap文件夹 - 选中所有要转换的图片(按
Ctrl+A全选,或者按住Ctrl多选特定图片) - 右键点击选中的图片,选择Convert to WebP
- 在弹出的对话框里:
- 调整Quality(质量,默认85就行)
- 勾选Skip images that are already WebP,避免重复转换已有的WebP图
- 要是确定不需要原图了,就勾选Delete original files
- 点OK,Studio就会自动帮你完成转换,要么替换原图,要么和原图并存,全看你选的选项。
方法三:自定义Gradle任务(适合特殊需求)
要是AGP的内置功能满足不了你的特殊需求(比如只想转换特定目录的图片、自定义转换参数之类的),可以写个自定义Gradle任务:
Groovy版本:
android { // ... 你的其他配置 } // 定义转换WebP的任务 task convertImagesToWebp(type: Exec) { // 遍历res目录下的png/jpg/jpeg,还可以用exclude排除不需要转换的文件 def imageFiles = fileTree(dir: 'src/main/res', include: ['**/*.png', '**/*.jpg', '**/*.jpeg'], exclude: ['drawable-xxhdpi/do_not_convert_this.png']) imageFiles.each { file -> // 生成WebP文件的路径,把原后缀换成.webp def webpFile = new File(file.parent, file.name.replaceAll(/\.(png|jpg|jpeg)$/, '.webp')) // 只有当WebP文件不存在,或者原图比WebP新的时候才转换,避免重复工作 if (!webpFile.exists() || file.lastModified() > webpFile.lastModified()) { // 获取Android SDK自带的cwebp工具路径,记得把34.0.0换成你本地的build-tools版本 def cwebpTool = "${android.sdkDirectory}/build-tools/34.0.0/cwebp" // Windows系统要加.exe后缀 if (OperatingSystem.current().isWindows()) { cwebpTool += ".exe" } // 执行转换命令,-q是质量参数,可按需调整 commandLine cwebpTool, file.absolutePath, "-q", "85", "-o", webpFile.absolutePath println "搞定:${file.name} 转成WebP啦" } } } // 让这个转换任务在构建APK之前自动执行 preBuild.dependsOn(convertImagesToWebp)
Kotlin DSL版本:
android { // ... 你的其他配置 } // 注册转换WebP的任务 tasks.register<Exec>("convertImagesToWebp") { val imageFiles = fileTree("src/main/res") { include("**/*.png", "**/*.jpg", "**/*.jpeg") exclude("drawable-xxhdpi/do_not_convert_this.png") // 排除不需要转换的文件 } imageFiles.forEach { file -> val webpFile = File(file.parent, file.name.replace(Regex("\\.(png|jpg|jpeg)$"), ".webp")) if (!webpFile.exists() || file.lastModified() > webpFile.lastModified()) { val cwebpTool = "${android.sdkDirectory}/build-tools/34.0.0/cwebp".let { // Windows系统加.exe后缀 if (org.gradle.internal.os.OperatingSystem.current().isWindows) "$it.exe" else it } commandLine(cwebpTool, file.absolutePath, "-q", "85", "-o", webpFile.absolutePath) println("搞定:${file.name} 转成WebP啦") } } } // 绑定到preBuild任务,构建前自动执行 tasks.preBuild.dependsOn(tasks.named("convertImagesToWebp"))
注意:记得把build-tools/34.0.0换成你本地安装的build-tools版本,你可以在Android Studio的SDK Manager里查看已安装的版本。
内容的提问来源于stack exchange,提问作者Long Thanh
相关产品推荐
相关产品推荐

