문서 목차
이 페이지에서목차

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.pngiOS light, Web 일반불투명 풀블리드 배경
ic_logo_rectangle_dark.pngiOS dark별도 dark 아트
ic_logo_rectangle_tinted.pngiOS tinted그레이스케일 전용
ic_background.png 또는 색상 설정Android adaptive 배경마크 없는 단색
ic_foreground.pngAndroid adaptive 전경투명 캔버스, 실제 잉크가 안전 원 내부
ic_black_white.pngAndroid monochrome투명 캔버스, 동일한 안전 원 검사
ic_logo_round.pngAndroid round완성된 원형 아트
ic_logo_macos.pngmacOS전 픽셀 불투명 풀블리드, 컴파일 인코딩 검사
ic_logo_windows.png Windows ICO, 레거시 Android, favicon 투명 모서리를 포함한 완성 아트
ic_logo_linux.pngLinux실제 패키징 경로에 연결할 완성 아트
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 해시를 확인한다. 기존 사용자 변경을 보존하고 이번 생성으로 생긴 무관한 변경만 제거한다. 보고에는 소스 검사 / 생성물 검사 / 컴파일 / 실제 설치 확인 중 수행한 범위를 명시한다.

검색어를 입력하면 문서를 찾습니다.

↑ ↓ 이동 · Enter 열기Esc 닫기