使用js脚本自动生成android项目的app icon图标

发布于:2025-04-10 ⋅ 阅读:(31) ⋅ 点赞:(0)

因为我的一个项目是使用GitHub action来实现编译和部署的,而且这个android项目的icon很有可能会发生变化,所以需要在脚本中实现自动化生成icon的功能,所以这里就写了一个js脚本来做这个事情

这个脚本可以输入一个图片地址,然后生成android项目的icon图标。

脚本文件内容:

const sharp = require('sharp')
const fs = require('fs-extra')
const path = require('path')
const { program } = require('commander')

const DENSITIES = {
    mdpi: 48,
    hdpi: 72,
    xhdpi: 96,
    xxhdpi: 144,
    xxxhdpi: 192,
}

program
    .requiredOption('-i, --input <file>', 'Path to source PNG')
    .option('-o, --output <dir>', 'Output directory', 'res')
    .option('--rounded', 'Apply circular mask to icons')
    .option('--copy-to <androidResDir>', 'Copy icons to Android res directory')

program.parse(process.argv)
const options = program.opts()

async function generateAdaptiveIcons(input, outputDir) {
    for (const [dpi, size] of Object.entries(DENSITIES)) {
        const mipmapDir = path.join(outputDir, `mipmap-${dpi}`)
        await fs.ensureDir(mipmapDir)
        const foregroundPath = path.join(
            mipmapDir,
            'ic_launcher_foreground.png'
        )
        const backgroundPath = path.join(
            mipmapDir,
            'ic_launcher_background.png'
        )
        const legacyPath = path.join(mipmapDir, 'ic_launcher.png')

        const img = sharp(input).resize(size, size)
        const rounded = options.rounded
            ? img.composite([
                  {
                      input: Buffer.from(
                          `<svg><circle cx="${size / 2}" cy="${size / 2}" r="${
                              size / 2
                          }" fill="white"/></svg>`
                      ),
                      blend: 'dest-in',
                  },
              ])
            : img

        await rounded.toFile(foregroundPath)
        await sharp({
            create: {
                width: size,
                height: size,
                channels: 4,
                background: '#FFFFFF',
            },
        })
            .png()
            .toFile(backgroundPath)

        // legacy fallback
        await rounded.toFile(legacyPath)
    }

    // Generate XML
    const xmlPath = path.join(outputDir, 'mipmap-anydpi-v26')
    await fs.ensureDir(xmlPath)
    await fs.writeFile(
        path.join(xmlPath, 'ic_launcher.xml'),
        `
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@mipmap/ic_launcher_background"/>
    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
  `.trim()
    )

    await fs.writeFile(
        path.join(xmlPath, 'ic_launcher_round.xml'),
        `
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@mipmap/ic_launcher_background"/>
    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
  `.trim()
    )

    console.log('✅ Adaptive icons generated.')
}

;(async () => {
    const { input, output, copyTo } = options
    const outPath = path.resolve(output)
    await generateAdaptiveIcons(input, outPath)

    if (copyTo) {
        const dest = path.resolve(copyTo)
        await fs.copy(outPath, dest, { overwrite: true })
        console.log(`📦 Icons copied to Android res dir: ${dest}`)
    }
})()

使用说明:

node ./generateIcons.cjs -i pakeplus.png --copy-to app/src/main/res

生成圆角图标:

node ./generateIcons.cjs -i pakeplus.png --rounded --copy-to app/src/main/res

最后生成的结果:


网站公告

今日签到

点亮在社区的每一天
去签到