apk图片资源优化,减小APK大小

png, svg转矢量图,webp到底用什么格式的图片呢?

在Android开发中选择图片资源格式(PNG、SVG、WebP)需综合考虑​​应用场景、性能需求、兼容性及维护成本​​。以下是综合判定逻辑及实践建议:


📊 ​​一、核心格式特性对比​

​格式​​优势​​劣势​​适用场景​​性能影响​
​PNG​​<br>(位图)无损压缩、支持透明度、显示质量高文件体积大、多分辨率需多套资源1. 带透明度的UI元素(按钮/图标)<br>2. 细节丰富的静态图(如插画)内存占用高(与分辨率正相关)

1

3

​SVG​​<br>(矢量图)无限缩放不失真、单文件适配多分辨率、体积小复杂图形渲染耗CPU、不支持投影/模糊等特效1. 纯色图标/简单图形<br>2. Material Design图标<br>3. 需要动态修改颜色的元素CPU渲染开销大(尤其复杂SVG)<br>内存占用可能高于PNG

6

7

​WebP​​<br>(位图)高压缩率(比PNG小26%↑,比JPEG小25%~34%)、支持有损/无损/透明度/动画低版本Android需兼容库(API<14)、转换工具少1. 网络传输图片(缩略图/背景)<br>2. 需平衡质量与体积的场景<br>3. 替代GIF的动画解码速度慢于JPEG 1.5倍,但加载更快(体积优势)

9

10


所以基本一些简单的icon,可以用svg

大图网图 webp

复杂或者不太大的图片png

由于历史遗留项目,用了很多PNG图片,导致APK包要一百多M。

优化思路,将部分PNG图片转换成webp

那是全部都要转换吗?

大概一个判断标准

推荐的图片大小判断标准(基于 Android 性能优化实践)

图片大小转换决策原因和说明
<2KB❌ 不要转换原始 PNG 头信息比 WebP 更小,转换后反而可能增大约 100-300 字节
2KB-10KB⚠️ 可选转换转换后能节省约 15-30% 空间,但对整体包大小影响有限
10KB-50KB✅ 强烈推荐转换转换后能节省 25-40% 空间,有明显收益
>50KB✅ 必须转换转换后节省可达 40-70%,对 APK 大小影响显著

基于上面的标准

我把阈值设置在30k

大致脚本文件如下 findlargepngs.ps1

param(
    [Parameter(Mandatory=$false, HelpMessage="Target directory path")]
    [string]$TargetPath = (Get-Location).Path,
    
    [Parameter(Mandatory=$false, HelpMessage="Minimum file size in KB")]
    [int]$MinSizeKB = 30
)

# Set encoding to UTF-8 to try to avoid any encoding issues
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8

# Check if directory exists
if (-not (Test-Path -Path $TargetPath -PathType Container)) {
    Write-Host "Error: Directory does not exist - $TargetPath" -ForegroundColor Red
    exit 1
}

# Check if cwebp is available
$cwebpPath = "cwebp.exe"
if (-not (Get-Command $cwebpPath -ErrorAction SilentlyContinue)) {
    Write-Host "Warning: cwebp.exe not found." -ForegroundColor Yellow
    Write-Host "Download from: https://developers.google.com/speed/webp/download and add to PATH" -ForegroundColor Cyan
    Write-Host "OR provide full path to cwebp.exe" -NoNewline
    $cwebpPath = Read-Host
    if (-not (Test-Path $cwebpPath)) {
        Write-Host "cwebp.exe not found at provided path. Exiting." -ForegroundColor Red
        exit 1
    }
}

# Create log file
$logPath = Join-Path -Path $TargetPath -ChildPath "PNG_WebP_Conversion_Log.txt"
"=== PNG to WebP Conversion Log ===" | Out-File $logPath
"Time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" | Out-File $logPath -Append
"Directory: $TargetPath" | Out-File $logPath -Append
"Minimum Size: ${MinSizeKB}KB" | Out-File $logPath -Append
"" | Out-File $logPath -Append

Write-Host "`nScanning directory: $TargetPath"
Write-Host "Looking for PNG files larger than ${MinSizeKB}KB..." -ForegroundColor Cyan

# Find PNG files larger than the threshold
$minSizeBytes = $MinSizeKB * 1024
$largePngs = Get-ChildItem -Path $TargetPath -Recurse -Include "*.png" -ErrorAction SilentlyContinue | 
    Where-Object { $_.Length -gt $minSizeBytes } 

$totalCount = $largePngs.Count
if ($totalCount -eq 0) {
    Write-Host "No PNG files found larger than ${MinSizeKB}KB." -ForegroundColor Yellow
    "No eligible files found." | Out-File $logPath -Append
    exit
}

Write-Host "Found $totalCount files to convert."

# Conversion process
$successCount = 0
$skippedCount = 0
$failedCount = 0
$totalSpaceSaved = 0

foreach ($png in $largePngs) {
    $pngPath = $png.FullName
    $webpPath = [System.IO.Path]::ChangeExtension($pngPath, "webp")
    $originalSize = $png.Length / 1KB
    $originalSize = [math]::Round($originalSize, 2)
    
    Write-Host "`nProcessing: $($png.Name) [$originalSize KB]"
    "Processing file: $pngPath" | Out-File $logPath -Append
    "Original size: $originalSize KB" | Out-File $logPath -Append
    
    try {
        # Convert: Use lossless if transparent, otherwise lossy with quality 80
        $hasTransparency = $false
        try {
            # Check for transparency using ImageMagick (if available) or assume false
            $hasTransparency = & magick identify -format "%[opaque]" $pngPath 2>$null
            $hasTransparency = ($hasTransparency -eq "false")
        } catch {
            $hasTransparency = $false
        }

        if ($hasTransparency) {
            & $cwebpPath -lossless -mt "$pngPath" -o "$webpPath"
        } else {
            & $cwebpPath -q 80 -mt "$pngPath" -o "$webpPath"
        }
        
        if ($LASTEXITCODE -ne 0) {
            throw "Conversion failed with error code: $LASTEXITCODE"
        }
        
        # Check if WebP file was created
        if (-not (Test-Path $webpPath)) {
            throw "WebP file not created after conversion."
        }
        
        $webpSize = (Get-Item $webpPath).Length / 1KB
        $webpSize = [math]::Round($webpSize, 2)
        $spaceSaved = $originalSize - $webpSize
        
        # Check if the new file is actually smaller
        if ($webpSize -ge $originalSize) {
            "Warning: Converted file not smaller ($originalSize KB → $webpSize KB)" | Out-File $logPath -Append
            Write-Host "  Warning: Converted file not smaller ($originalSize KB → $webpSize KB)" -ForegroundColor Yellow
            
            # Remove the WebP file and skip
            Remove-Item -Path $webpPath -Force -ErrorAction SilentlyContinue
            $skippedCount++
        } else {
            # Calculate space saved
            $spaceSaved = [math]::Round($spaceSaved, 2)
            $savedPercent = [math]::Round(($spaceSaved / $originalSize) * 100, 1)
            $totalSpaceSaved += $spaceSaved
            
            # Backup the original PNG (optional)
            #$backupPath = $pngPath + ".orig"
            #Copy-Item -Path $pngPath -Destination $backupPath -Force -ErrorAction SilentlyContinue
            
            # Replace the original with WebP
            Remove-Item -Path $pngPath -Force
            "Converted successfully: $originalSize KB → $webpSize KB, Saved $spaceSaved KB ($savedPercent%)" | Out-File $logPath -Append
            Write-Host "  Converted successfully: Saved $spaceSaved KB ($savedPercent%)" -ForegroundColor Green
            $successCount++
        }
    } catch {
        $errorMsg = $_.Exception.Message
        "Error: $errorMsg" | Out-File $logPath -Append
        Write-Host "  Error: $errorMsg" -ForegroundColor Red
        $failedCount++
    }
}

# Generate report
$endTime = Get-Date
$elapsedTime = New-TimeSpan -Start (Get-Date) -End $endTime | ForEach-Object { $_.TotalMinutes }
$elapsedTime = [math]::Round($elapsedTime, 1)

# Output results
Write-Host "`n================================================" -ForegroundColor Cyan
Write-Host "Conversion Complete!" -ForegroundColor Green
Write-Host "Total files: $totalCount" 
Write-Host "Successfully converted: $successCount" -ForegroundColor Green
Write-Host "Skipped (not smaller): $skippedCount" -ForegroundColor Yellow
Write-Host "Failures: $failedCount" -ForegroundColor Red
Write-Host "Total space saved: $([math]::Round($totalSpaceSaved, 2)) KB" -ForegroundColor Cyan
Write-Host "Time elapsed: $elapsedTime minutes" -ForegroundColor Cyan
Write-Host "Log file: $logPath" -ForegroundColor Magenta
Write-Host "================================================" -ForegroundColor Cyan

命令行运行,添加目标地址

.\findlargepngs.ps1 -TargetPath "E:\workspace\xxxx\src\main"

即可将png转换成webp

最后APK大小成功减小50%

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值