Community이미지github.com

Store-Screenshots 앱스토어 & 구글플레이 스크린샷 자동 생성

iOS 시뮬레이터와 Android 에뮬레이터에서 실제 화면을 캡처하고 HTML Canvas 위에 기기 프레임, 헤드라인, 설명을 합성하여 App Store 및 Google Play에 필요한 스크린샷 세트를 생성합니다. 코드베이스에서 앱의 장점을 찾아 모든 언어와 기기 크기별로 정확한 이미지를 만들어냅니다.

Store-Screenshots 앱스토어 & 구글플레이 스크린샷 자동 생성란 무엇인가요?

이 스킬은 개발자가 코드베이스에서 앱의 핵심 장점을 추출하고, iOS 시뮬레이터(iPhone, iPad, iPhone Duo)와 Android 에뮬레이터(휴대폰, 태블릿)에서 실제 화면을 캡처한 뒤, HTML Canvas 위에 기기 프레임, 헤드라인, 설명을 입혀 App Store와 Google Play에 최적화된 스크린샷 세트를 생성하는 엔드투엔드 도구입니다. 각 텍스트 문자열은 `locales/<locale>.json` 파일에 저장되어 새 언어 추가가 JSON 파일 하나와 캡처로 간단하며, 동일한 입력이 동일한 픽셀을 보장하는 결정론적 렌더링 방식을 사용합니다. 주요 워크플로는 장점 분석 → 슬라이드 정의 → 캡처 설정 → 시뮬레이터 캡처 → HTML Canvas 구성(배경, 헤드라인, 기기 프레임, 3D로 돌출된 브레이크아웃) → 모든 로케일×기기 조합 렌더링 → 검토로 이어집니다. Claude Code, Cursor, Codex 등의 AI 에이전트에서 실행 가능하며, React Native, Flutter 등 크로스플랫폼 앱은 Android 캡처를 건너뛰고 iOS 캡처를 재사용할 수 있고, 네이티브 Android 앱은 별도 캡처가 가능합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/meth0xy/store-screenshots/tree/HEAD/skills/store-screenshots

Installed? Explore more 이미지 skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

당신은 스크린샷 세트를 생성된 이미지가 아닌 데이터로 구축합니다. 각 타일은 레이어로 구성된 HTML Canvas입니다: 배경, 헤드라인, 실제 캡처를 담은 기기 프레임, 그리고 3D로 화면 밖으로 돌출된 브레이크아웃(캡처의 일부 또는 벡터 설명)으로 이루어집니다. 모든 문자열은 locales/<locale>.json에 저장되므로, 새 언어는 JSON 파일 하나와 캡처만 추가하면 되며, 렌더링은 결정론적입니다: 동일한 입력은 동일한 픽셀을 보장합니다.

$S는 이 SKILL.md 파일이 위치한 폴더, $PY는 $S/.venv/bin/python입니다. 가상 환경이 없으면 한 번 생성하세요:

python3 -m venv $S/.venv && $S/.venv/bin/pip install -r $S/requirements.txt && $S/.venv/bin/playwright install chromium

파이프라인:

1 장점 -> 2 슬라이드 -> 3 capture.json -> 4 캡처 (시뮬레이터) -> 5 구성
-> 6 배경 -> 7 set.json + 로케일 -> 8 렌더링 -> 9 검토 -> (더 많은 언어, 기기)

저장소의 $S/../../examples/demo/는 완전한 프로젝트 예제입니다 (가상 앱, 2개 언어, 5개 기기). 직접 작성하기 전에 set.json을 읽어보세요.

프로젝트 구조

<project>/
  capture.json                  앱, 캡처 기기, 캡처할 화면
  set.json                      모든 로케일이 공유하는 구성
  locales/<locale>.json         모든 문자열: 동사, 설명, 설명 텍스트
  sim/<locale>/<slide>.png      폰 캡처 (캡처 세트당 하나의 폴더)
  sim-tablet/  sim-duo/  sim-android/
  fonts/  assets/               선택적 폰트, 배경 이미지, 소품
  out/<locale>/<device>/        스토어 파일만
  out/_sheets/                  로케일 및 기기별 연락처 시트
  out/_captures/                캡처 후 로케일별 연락처 시트

앱 저장소 루트에 store-screenshots/를 권장합니다. out/과 .cache/를 .gitignore에 추가하세요.


1. 장점

코드베이스를 읽으세요: 네비게이션 (탭, 라우트, 화면), 온보딩 문구, 페이월 문구, README, 기존 스토어 등록 정보를 확인합니다. 사용자가 앱을 설치하게 할 만한 5~8가지 항목을 순위별로 나열하세요. 슬라이드당 하나의 장점입니다.

각 슬라이드 헤드라인은 대문자로 된 하나의 짧은 동사와 최대 두 줄의 설명으로 구성됩니다: PLAN / YOUR WEEK IN MINUTES, SAVE / ON EVERY SHOP. 동사는 장점을 나타내며 기능을 나타내지 않습니다. 각 장점을 증명하는 화면과 함께 목록을 보여주고 승인을 받으세요.

2. 슬라이드

ID는 NN-name 형식이며, 숫자는 스토어에서의 위치입니다. 슬라이드당 화면을 선택하고 필요한 상태(로그인, 데이터 존재, 시트 열림 등)를 기록하세요. 이미지가 많은 화면은 기울이고, 데이터가 많은 화면은 수직으로 유지하세요.

3. capture.json

$S/templates/capture.json에서 시작하세요.

키의미
app.iosbundleId, 그리고 app (시뮬레이터 .app 빌드 경로) 또는 copyFrom (앱이 설치된 시뮬레이터 UDID)
app.androidpackage, 선택적 activity, 선택적 apk 설치 경로
devices.<key>platform ios 또는 android, dir (캡처 폴더), iOS: name (전용 시뮬레이터, setup으로 생성) 및 type (xcrun simctl list devicetypes), 선택적 runtime; Android: avd (emulator -list-avds)
기기 추가 설정appearance (light), locale (아래 모드 재정의), displaySize (2853x2007은 iPhone Duo 내부 디스플레이 선택), rotate (도, 캡처가 옆으로 나올 때)
locale플랫폼별. iOS reboot (기본값, 가장 안정적), relaunch (재부팅 없음, 폴더블 자세 유지) 또는 launchArgs. Android app (기본값, Android 13+에서 앱별 언어, 앱의 localeConfig 필요) 또는 system (루트 권한이 있는 에뮬레이터 이미지 필요)
launch실행 후 wait 초, 선택적 url (앱 대신 열 URL, Expo dev client URL), 선택적 steps
screens{id, steps, ready, after, devices, copyFrom} 목록, 각 화면에 병합되는 byDevice / byLocale 블록 포함

단계는 순서대로 실행되며 각각 대기합니다 (wait, 기본 1~2초):

단계효과
{"open": "myapp://route"}딥링크. 탭보다 권장: 모든 기기와 플랫폼에서 작동
{"tap": {"label": "Save"}}해당 접근성 레이블이 있는 요소 탭 (또는 {"id": ...}), 정확히 일치 후 부분 문자열 일치
{"tap": {"at": [0.5, 0.9]}}화면 분율 위치 탭
{"tap": {...}, "until": {"label": "Details"}}해당 요소가 나타날 때까지 최대 3회 탭 반복; 아직 안정화되지 않은 화면의 탭에 사용
{"waitFor": {"label": "Done", "timeout": 20}}로드되거나 애니메이션 중인 화면에서 탭 전에 요소가 화면에 나타날 때까지 대기
{"type": "pasta"}, {"key": "enter"}, {"key": "back"}텍스트 및 키 입력
{"swipe": [0.5, 0.8, 0.5, 0.3]}스와이프, 분율 좌표
{"launch": true}앱 재시작

ready: {"region": [x, y, w, h], "minStd": 20, "tries": 5, "delay": 3}는 해당 영역이 단색(스켈레톤 행, 스피너, 로딩 중인 이미지)일 때 재촬영합니다. iPhone 캡처는 시뮬레이터가 Dynamic Island를 화면에 구울 때 자동으로 재촬영됩니다.

copyFrom: "01-home"는 해당 기기의 다른 캡처를 재사용합니다 (태블릿이 분할 보기에서 두 화면을 표시하는 경우). devices: ["phone"]는 특정 화면을 일부 기기로 제한합니다.

capture.py PROJECT describe --device phone는 레이블과 프레임이 있는 탭 가능한 요소를 출력합니다.

4. 캡처

$PY $S/capture.py <project> doctor              # 도구, 기기, 앱 ID 확인
$PY $S/capture.py <project> setup               # 전용 시뮬레이터 생성/부팅, AVD 부팅, 앱 설치
$PY $S/capture.py <project> run --locale en-US  # 모든 기기와 화면 캡처
$PY $S/capture.py <project> run --locale en-US --device phone --screen 03-search
  • 캡처 기기는 전용입니다: iOS 시뮬레이터는 이름으로 생성되고 (Capture iPhone ...), Android는 capture.json에 지정된 AVD를 사용합니다. capture.json을 사용자가 작업 중인 시뮬레이터로 지정하지 말고, 기기를 부팅하거나 언어를 변경하기 전에 물어보세요.
  • setup 후, 앱은 일반적으로 데모 상태가 필요합니다: 데모 계정 로그인, 데이터 시드, 첫 실행 대화상자(비밀번호 저장, 알림, 리뷰 요청) 해제. 기기당 한 번 수행하면 상태가 언어 변경 후에도 유지됩니다. 사용자에게 데모 자격 증명을 요청하고 capture.json에 절대 직접 기록하지 마세요.
  • 디버그 오버레이(개발 메뉴 버튼, 토스트)를 표시하는 개발 빌드는 캡처 세션 동안 이를 숨겨야 합니다. 로컬에서 패치하고 커밋하지 마세요.
  • out/_captures/<locale>.jpg를 타일별로 검토하세요: 다른 언어 문자열, 다이얼로그, 토스트, 스피너, 빈 상태가 없어야 합니다. 데이터 또는 단계를 수정하고 해당 화면을 다시 실행하세요. 렌더러는 캡처를 그대로 표시합니다; 실수를 덮어쓰지 않습니다.
  • iPhone Duo: 시뮬레이터 또는 DeviceHub에서 먼저 시뮬레이터를 펼치고 가로 모드로 설정하세요; simctl은 접거나 회전할 수 없습니다. 딥링크 사용(HID 탭이 내부 디스플레이에 도달하지 못할 수 있음), "locale": "relaunch" 및 "displaySize": "2853x2007"를 사용하세요.

크로스플랫폼 앱(React Native, Flutter)은 Android 캡처를 건너뛸 수 있습니다: Android 타일은 iPhone 및 iPad 캡처를 재사용하며, 이것이 기본 기기의 동작입니다. 네이티브 Android 앱은 자체 화면을 sim-android/에 캡처합니다(10절 참조).

5. 구성 (렌더링 전 사용자 승인 필요)

각 슬라이드를 ASCII로 스케치하세요: 헤드라인, 기기 위치 및 기울기, 어떤 요소가 돌출되고 어디에 배치될지. 승인을 받은 후 set.json을 작성하세요.

 +------------------------------+
 |            WATER             |  동사, 한 줄
 |      EVERY PLANT RIGHT       |  설명, 최대 2줄
 |          ON TIME             |
 |      .--------------.        |
 |  [* 3 plants today]          |  설명, 돌출, 왼쪽으로 나옴
 |      |  Today ...   |        |  기기 기울기 y 15, x 4
 +------------------------------+

6. 배경

세트당 하나의 배경, 모든 로케일과 기기가 공유합니다. CSS ("background": {"css": "radial-gradient(...), #1f4a37"}, 데모에서 사용) 또는 이미지 ({"image": "assets/bg.png"}, background-size cover) 중 하나입니다. 이미지 생성기는 부드러운 판에 잘 맞습니다; 브랜드 색상에 부드러운 조명이 있는 9:16 시즌리스 스튜디오 배경을 프롬프트하고 명시적으로: 물체 없음, 텍스트 없음, 기기 없음, 도형 없음. 두 개를 생성하고 사용자가 선택합니다. 소품(스티커, 제품 사진)은 알파 채널이 있는 PNG로 슬라이드당 배치됩니다.

7. set.json 및 로케일

모든 사각형은 눈으로 측정하지 말고 캡처 픽셀 단위로 measure.py로 측정하세요:

$PY $S/measure.py sim/en-US/05-fill.png --at 700,790            # 버튼, 칩, 알약을 플러드 필
$PY $S/measure.py sim/en-US/01-plan.png --ink 40,415,700,75     # 평평한 영역의 텍스트 범위
$PY $S/measure.py sim/en-US/02-cook.png --grid 440,1510,340,110  # 임시 디렉토리의 확대 그리드 이미지
키의미
locales, devices전체 렌더링이 다루는 대상; device id는 $S/devices/devices.json에서 가져옴
background{"image": ...} 또는 {"css": ...}, 선택적 position
fonts{"family": "fonts/File.otf"}, 경로는 프로젝트 기준; 기본 display는 번들된 Archivo Black
headlinefont, descFont, verbColor, descColor, shadow, verbTracking, descTracking, descWordSpacing
captureplatform, statusBarBand (캡처 행 블렌드 제거, iOS 기본 [66, 128]), sets ({"tablet": {"dir": "sim-tablet", "statusBarBand": [12, 56]}}), devices ({"android-phone": "android"}로 기기를 다른 캡처 세트로 지정)
stylegloss, deviceShadow, thicknessRatio (측면 벽 깊이), sideLayers
statusBar렌더러가 그리는 상태 표시줄의 time, color
layoutdevice id별로, devices.json 레이아웃 재정의 (deviceTop, deviceWidth, verbMax ...)
baseline라이브 세트의 {device: {locale: folder}}, --compare용
slides아래 목록

슬라이드: id, sim (캡처 파일, <id>.png가 아닌 경우), tilt {x, y, z} 도, offset {x, y} 캔버스 분율, layout, breakouts, props (src, x, y, w 캔버스 분율, rotate, shadow, z: front 또는 back).

브레이크아웃:

키의미
typecrop: 캡처 자체 픽셀; callout: 로케일 텍스트가 있는 벡터 알약
rect 또는 anchor[x, y, w, h] 캡처 픽셀 단위, 가져오는 요소의 위치
at 또는 dx/dy배치 위치 (at = 캡처 픽셀 단위 새 왼쪽 위 모서리) 또는 오프셋
scale, lift크기 및 z 리프트 (픽셀, 기본 80)
vacate, vacatePad원래 위치를 주변 색상으로 채움 (복사가 아닌 이동)
radius, shadow, origin모서리 반경 (캡처 픽셀), 그림자 강도, 변환 원점
text, icon, style설명: 로케일의 callouts 키, tag 또는 sparkles, 그리고 font, size, bg, fg, padX, padY, gap, radius, weight, tracking, iconScale, iconColor

slides 내의 모든 값은 기기 및 로케일별로 다를 수 있습니다: {"byDevice": {"phone": ..., "tablet": ..., "default": ...}} (키: device id, 캡처 세트, default) 및 {"byLocale": {"de-DE": ..., "default": ...}}, 서로 중첩 가능. 사각형은 거의 항상 로케일별로 다릅니다. 동일한 칩이라도 독일어에서는 더 넓기 때문입니다.

크롭은 큰 요소의 경우 약 1.7배까지 선명도를 유지합니다. 작은 칩과 텍스트는 설명(벡터)이 되어 모든 배율에서 선명도를 유지합니다.

로케일 파일:

{
  "captures": "en-US",
  "dir": "ltr",
  "fonts": {"display": "fonts/NotoSansJP-Black.otf"},
  "slides": {
    "01-plan": {"verb": "Plan", "desc": "Your week in minutes", "callouts": {"savings": "approx. €7.81 saved"}}
  }
}

slides만 필수입니다. captures는 로케일이 다른 로케일의 캡처를 재사용하게 합니다 (en-GB가 en-US를 읽음). headline과 statusBar는 set.json을 재정의합니다. Archivo Black은 라틴 문자만 지원합니다; 키릴 문자, 그리스 문자, CJK, 아랍어, 히브리어는 fonts 재정의가 필요하고, RTL은 "dir": "rtl"이 필요합니다.

8. 렌더링

$PY $S/render.py <project>                                  # 전체 렌더링
$PY $S/render.py <project> --locale de-DE --device iphone-67 --slide 01-plan
$PY $S/render.py <project> --compare                        # 기준 vs 새 시트 비교

헤드라인 크기는 로케일과 기기의 모든 슬라이드에서 공유되므로 세트가 하나로 읽힙니다. 캡처의 가로세로 비율이 기기의 화면 개구부와 일치하지 않으면 렌더러가 중단됩니다.

9. 검토

out/_sheets/<locale>-<device>.jpg를 열고 모든 브레이크아웃을 확대하세요. CHECK로 출력된 줄은 문제를 식별합니다 (헤드라인이 최소 크기, 겹침). 헤드라인이 최소 크기라는 것은 카피가 너무 긴 것입니다: 제한을 낮추지 말고 카피를 줄이세요. 시트를 사용자에게 보여주세요.

10. 더 많은 언어 및 기기

언어 추가:

$PY $S/add_locale.py <project> es-ES init --from en-US     # 로케일 파일, byLocale 플레이스홀더, 폴더
$PY $S/capture.py <project> run --locale es-ES             # 캡처
#   locales/es-ES.json 번역: 스토어 카피, 짧은 동사, 캡처와 일치하는 설명
$PY $S/add_locale.py <project> es-ES measure --from en-US  # 사각형 재탐색, 나란히 이미지 검토
$PY $S/add_locale.py <project> es-ES measure --from en-US --write
$PY $S/add_locale.py <project> es-ES check                 # 렌더링 전 오류 0개 확인
$PY $S/render.py <project> --locale es-ES

지역 변형 (en-GB, de-AT, fr-CA): init --share-captures, 텍스트만 변경됩니다.

$S/devices/devices.json의 기기:

id캔버스읽기스토어 슬롯
iphone-671290x2796폰 (1206x2622)ASC APP_IPHONE_67
android-phone1080x1920폰Play 폰 스크린샷
ipad-132064x2752태블릿 (2064x2752)ASC APP_IPAD_PRO_3GEN_129
android-tablet1792x2400태블릿Play 7" 및 10" 태블릿
iphone-duo2853x2007듀오 (2853x2007)ASC iPhone Duo

프레임은 make_frame.py로 만든 일반 도면이며 무료로 재배포할 수 있습니다. 일치하는 프레임이 없는 캡처 크기는 새로 생성됩니다:

# 네이티브 Android 캡처, 1080x2400, sim-android/에 저장
$PY $S/make_frame.py --style android --screen 1080x2400 --device android-phone --captures android
# 그런 다음 set.json에서: "capture": {"sets": {"android": {"dir": "sim-android", "statusBarBand": [30, 105]}}}

스타일: ios, android, tablet, landscape. --canvas WxH는 새 device id의 스토어 크기를 설정합니다. 실제 캡처에서 statusBarBand를 측정하세요: 상태 표시줄의 행 + 약간의 여유.

관련 스킬