Reference Utility Build Tools

Density-Aware Asset Rasterization

A modern Python replacement for a 2016 VBScript workflow that rasterized SVG artwork into Android drawable and mipmap density folders.

Problem Mobile projects need repeatable raster assets at several pixel densities, but manual export creates inconsistent sizes and stale files.
Outcome A small command-line script that maps SVG names to Android resource folders and renders the required PNG sizes.

This modernizes the 2016 Android image script. The original used VBScript, Inkscape, ImageMagick, pngquant, and pngout. The durable mechanism is still useful: keep vector artwork as source, encode size rules in one place, and regenerate density-specific raster outputs on demand.

Code

from __future__ import annotations

import argparse
import subprocess
from pathlib import Path


ICON_SIZES = {
    "drawable-mdpi": 48,
    "drawable-hdpi": 72,
    "drawable-xhdpi": 96,
    "drawable-xxhdpi": 144,
    "drawable-xxxhdpi": 192,
}

MENU_SIZES = {
    "drawable-mdpi": 24,
    "drawable-hdpi": 36,
    "drawable-xhdpi": 48,
    "drawable-xxhdpi": 72,
    "drawable-xxxhdpi": 96,
}

LAUNCHER_SIZES = {
    "mipmap-mdpi": 48,
    "mipmap-hdpi": 72,
    "mipmap-xhdpi": 96,
    "mipmap-xxhdpi": 144,
    "mipmap-xxxhdpi": 192,
}


def rules_for(svg: Path) -> dict[str, int]:
    name = svg.stem.lower()
    if name.startswith("ic_launcher"):
        return LAUNCHER_SIZES
    if name.startswith("ic_menu_"):
        return MENU_SIZES
    return ICON_SIZES


def render_svg(svg: Path, output: Path, size: int) -> None:
    output.parent.mkdir(parents=True, exist_ok=True)
    subprocess.run(
        [
            "magick",
            "-background",
            "none",
            str(svg),
            "-resize",
            f"{size}x{size}",
            str(output),
        ],
        check=True,
    )


def build_assets(source_dir: Path, res_dir: Path) -> None:
    for svg in sorted(source_dir.glob("*.svg")):
        for folder, size in rules_for(svg).items():
            output = res_dir / folder / f"{svg.stem}.png"
            render_svg(svg, output, size)


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("source_dir", type=Path)
    parser.add_argument("res_dir", type=Path)
    args = parser.parse_args()
    build_assets(args.source_dir, args.res_dir)


if __name__ == "__main__":
    main()

Usage

python build_android_assets.py images app/src/main/res

Put source SVG files in images/. Files named ic_launcher*.svg are written to mipmap-*, files named ic_menu_*.svg use menu icon sizes, and other files use regular drawable icon sizes.

How It Works

The filename selects a size map. Each size map names the Android resource directory and the target pixel dimension. The renderer writes transparent PNG files into the correct resource folders.

Notes

This version uses ImageMagick’s magick command because it is scriptable and current. If your project requires exact SVG rendering parity with Inkscape, replace render_svg with an Inkscape CLI call and keep the same size maps.

The original script also compressed recently changed PNG files with pngquant and pngout. Add that as a second pass if binary size matters for your build.

Source

Original article: A script to generate android images

Full Explanation

The 2016 post shows the original VBScript workflow and the Android density mappings that inspired this smaller cross-platform version.

The publishing loop Research → book → capstone → solution → real use → new evidence
Browse all solutions →