6개 플랫폼 앱 아이콘 재생성
Figma 원본 → PNG export → `icons_launcher` → 프로젝트별 경로 연결 → 산출물 검사 순서다.
Figma 원본 → PNG export → icons_launcher → 프로젝트별 경로 연결 → 산출물 검사 순서다.
Bottari FX 작업에서 icons_launcher 3.1.0으로 확인했다. 기존 프로젝트의 잠금 버전과 설정을 먼저
확인하고, 재생성만을 위해 의존성을 무조건 업그레이드하지 않는다.
1. 원본과 매핑을 고정한다#
Figma에 앱 아이콘 페이지를 만들고 기존 심볼의 연결된 인스턴스를 사용한다. 원본 비율·기울기를 보존하며 플랫폼별 크기와 시각적 중심을 조정한다. 가이드·런처 미리보기는 export 프레임과 분리한다. 1024×1024 프레임을 PNG 1x로 내보내고 밀도별 축소는 생성기에 맡긴다.
소스 예시 (assets/icons/) | 용도 | 확인할 점 |
|---|---|---|
ic_logo_rectangle_light.png | iOS light, Web 일반 | 불투명 풀블리드 배경 |
ic_logo_rectangle_dark.png | iOS dark | 별도 dark 아트 |
ic_logo_rectangle_tinted.png | iOS tinted | 그레이스케일 전용 |
ic_background.png 또는 색상 설정 | Android adaptive 배경 | 마크 없는 단색 |
ic_foreground.png | Android adaptive 전경 | 투명 캔버스, 실제 잉크가 안전 원 내부 |
ic_black_white.png | Android monochrome | 투명 캔버스, 동일한 안전 원 검사 |
ic_logo_round.png | Android round | 완성된 원형 아트 |
ic_logo_macos.png | macOS | 전 픽셀 불투명 풀블리드, 컴파일 인코딩 검사 |
ic_logo_windows.png |
Windows ICO, 레거시 Android, favicon | 투명 모서리를 포함한 완성 아트 |
ic_logo_linux.png | Linux | 실제 패키징 경로에 연결할 완성 아트 |
ic_web_maskable.png |
Web maskable | 별도 불투명 배경, 중요 마크를 중앙 안전 원 안에 배치 |
파일명은 예시다. 프로젝트 문서와 source-manifest.json에 Figma file key, page/node ID,
소스 파일 경로와 SHA-256을 남긴다. 다운로드용 임시 URL·인증 토큰은 저장하지 않는다.
Figma 수정 후에는 해당 프레임을 다시 export한다. 아래 명령은 로컬 PNG에서 파생 자산을 생성하며
Figma 최신 버전을 자동 다운로드하지 않는다.
2. 설정과 프로젝트 연결#
아래는 Bottari FX처럼 Linux runner가 linux/runner/resources/app_icon.png를 사용하는 구성이다.
색상·소스 매핑·경로는 대상 앱에 맞춘다.
icons_launcher:
platforms:
android:
enable: true
image_path: assets/icons/ic_logo_windows.png
adaptive_background_color: '#FFFFFF'
adaptive_foreground_image: assets/icons/ic_foreground.png
adaptive_round_image: assets/icons/ic_logo_round.png
adaptive_monochrome_image: assets/icons/ic_black_white.png
ios:
enable: true
image_path: assets/icons/ic_logo_rectangle_light.png
dark_path: assets/icons/ic_logo_rectangle_dark.png
tinted_path: assets/icons/ic_logo_rectangle_tinted.png
macos:
enable: true
image_path: assets/icons/ic_logo_macos.png
windows:
enable: true
image_path: assets/icons/ic_logo_windows.png
linux:
enable: false # 이 구성은 아래 wrapper가 runner의 실제 파일을 갱신
image_path: assets/icons/ic_logo_linux.png
web:
enable: true
image_path: assets/icons/ic_logo_rectangle_light.png
maskable_image_path: assets/icons/ic_web_maskable.png
favicon_path: assets/icons/ic_logo_windows.png
Linux의 enable: false는 공통 규칙이 아니다. 3.1.0의 Linux 생성기는 snap/gui/app.png와
Snap 템플릿을 생성한다. runner/CMake가 다른 아이콘을 읽으면 생성 성공만으로 적용되지 않는다.
실제 Snap 앱은 생성기를 활성화하고 desktop entry·snapcraft의 앱 ID와 배포 메타데이터를 확인한다.
기존 Snap 파일을 삭제하지 않는다. 다른 패키징은 CMake install, runner 로딩 경로,
.desktop의 Icon 참조까지 추적해 맞는 위치에 연결한다.
재생성 wrapper 예시 (tool/icons/generate.sh, 앱 위치 app/app):
#!/usr/bin/env bash
set -euo pipefail
project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
dart_bin="$project_root/.fvm/flutter_sdk/bin/dart"
[[ -x "$dart_bin" ]] || { echo '프로젝트에 고정된 Flutter SDK를 먼저 준비하세요.' >&2; exit 1; }
cd "$project_root/app/app"
"$dart_bin" run icons_launcher:create
cp assets/icons/ic_logo_linux.png linux/runner/resources/app_icon.png
# 별도 사이트가 이 favicon을 사용하는 프로젝트에서만 실행
cp web/favicon.png "$project_root/site/web/favicon.png"
bash tool/icons/generate.sh로 실행한다. 별도 사이트가 없다면 마지막 복사는 제외한다.
Web manifest와 사이트 HTML의 favicon 참조도 확인한다. 아이콘 변경에 스플래시 재생성은 필요하지 않다.
flavor 명령은 실제 native target/config가 존재할 때만 추가한다. 런타임 환경 구분만 있는 앱에
--flavor development를 무조건 실행하지 않는다. Windows처럼 출력 경로가 공유되는 플랫폼은
dev/stg 생성이 운영 아이콘을 덮어쓰지 않도록 설정하거나 마지막 운영 생성 결과를 검증한다.
3. 실제 PNG와 파생 산출물을 검사한다#
Android: bbox만으로는 통과시킬 수 없다#
안전 영역은 캔버스 지름의 61.1%인 원이다. bbox의 너비·높이가 61.1% 이하여도 대각선 끝이 원 밖으로 나갈 수 있다. 투명 전경·monochrome의 알파가 0보다 큰 픽셀을 모두 검사한다. 완성된 불투명 배경 이미지에는 이 검사를 적용하지 않는다.
아래는 Pillow가 설치된 환경에서 앱 디렉터리에서 실행하는 읽기 전용 검사다.
from pathlib import Path
from math import hypot
from PIL import Image
for name in ('ic_foreground.png', 'ic_black_white.png'):
with Image.open(Path('assets/icons') / name) as image:
assert 'A' in image.getbands(), f'{name}: 투명 전경이 아님'
alpha = image.getchannel('A')
width, height = image.size
assert width == height, f'{name}: 정사각 캔버스 필요'
bbox = alpha.getbbox()
assert bbox is not None, f'{name}: 빈 이미지'
# 픽셀 중심 기준. 아주 희미한 안티앨리어싱 픽셀도 포함한다.
radius = max(
hypot(x + 0.5 - width / 2, y + 0.5 - height / 2)
for y in range(height) for x in range(width)
if alpha.getpixel((x, y)) > 0
)
limit = min(width, height) * 0.611 / 2
print(name, 'bbox=', bbox, 'radius=', radius, 'limit=', limit)
assert radius <= limit, f'{name}: 안전 원 밖의 잉크 존재'
Bottari FX에서는 1024px 캔버스에 폭552px(53.9%) 심볼을 배치했지만 최대 잉크 반경386.3px로 안전 반경312.8px를 초과했다. 폭440px(43.0%)로 조정한 결과308.4px로 통과했다. 440px은 해당 심볼의 결과이며 다른 로고에 복사하는 상수가 아니다. 크기·시각적 위치를 변경할 때마다 다시 측정한다. 실제 adaptive 런처의 viewport 확대와 원본 export 크기를 구분한다. 미리보기를 크게 보이게 하려고 검증된 원본 foreground를 확대하지 않는다.
플랫폼별 검증 범위#
- Android: background 고유색 1개, foreground/monochrome 안전 원, 생성 XML의 참조 및 설치 후 원형·둥근 사각 런처에서 잘림·이중 마크를 확인한다.
- iOS: 생성된 light 1024px 이미지가 RGB이고 완전 불투명한지, Contents.json의 light/dark/tinted 연결을 확인한다. 원본의 불투명 RGBA와 실제 생성물의 채널을 구분한다.
- macOS: 전 픽셀 알파255와 컴파일된 AppIcon 렌디션을 확인한다. 컴파일 확인만으로 Dock의 실제 렌더링까지 검증했다고 보고하지 않는다. OS 합성 확인은 상위 스킬의 절차를 따른다.
- Windows: ICO에 필요한 크기가 포함되는지 확인한다. Bottari FX에서 확인한 크기는 16·24·32·48·64·96·128·256px이다. runner 리소스 참조와 실제 설치 아이콘을 별도로 확인한다.
- Linux: 실제 bundle에 복사되는 PNG와 runner/desktop entry 참조를 확인한다. 파일 생성만으로 데스크톱 메뉴·작업 표시줄까지 검증했다고 보고하지 않는다.
-
Web: 일반/maskable 아이콘과 manifest의
purpose, favicon 및 사이트 참조를 확인한다. maskable 중요 마크는 캔버스 지름80%의 중앙 원 내부에 유지한다.
전체 앱 빌드 전 macOS asset catalog만 검사하는 예시:
icon_check_dir="$(mktemp -d)"
mkdir -p "$icon_check_dir/compiled"
xcrun actool macos/Runner/Assets.xcassets \
--compile "$icon_check_dir/compiled" --platform macosx \
--minimum-deployment-target 26.0 --app-icon AppIcon \
--output-partial-info-plist "$icon_check_dir/info.plist"
xcrun assetutil --info "$icon_check_dir/compiled/Assets.car" \
| jq '[.[] | select(.AssetType == "Icon Image" and .Name == "AppIcon")
| {PixelWidth, Encoding, Colorspace}]'
deployment target와 catalog/name은 프로젝트 설정에 맞춘다. 출력이 비어 있으면 검증 실패다.
Gray 렌디션은 상위 스킬의 macOS 진단 절차로 해결한다.
마지막으로 git diff --stat, 변경 파일별 diff와 source-manifest 해시를 확인한다.
기존 사용자 변경을 보존하고 이번 생성으로 생긴 무관한 변경만 제거한다.
보고에는 소스 검사 / 생성물 검사 / 컴파일 / 실제 설치 확인 중 수행한 범위를 명시한다.