Play 피처 그래픽은 올린 그대로 보이지 않는다 — 좌우가 잘린다
Play 콘솔이 요구하는 피처 그래픽 규격은 1024×500 하나뿐이다. 그래서 그 캔버스를 기준으로 여백을 잡게 되는데, 검색 결과 화면에서 실제로 보이는 것은 좌우가 잘린 그림이다. 잘리는 양은 한쪽당 원본 기준 약 68px, 전체 폭의 13% 다.
이 사실을 모르면 “여백을 충분히 줬는데 왜 답답해 보이지”에서 멈추게 된다. 실측으로 확인한 과정과, 그래서 안전 영역을 어떻게 잡아야 하는지 정리한다.
어떻게 알아냈나 — 비율이 안 맞는다
스토어 검색 결과를 캡처해서 카드의 픽셀 좌표를 쟀다. 카드가 단색 배경이면 색으로 바로 분리된다.
from PIL import Image
import numpy as np
a = np.asarray(Image.open("shot.png").convert("RGB")).astype(int)
# 카드 배경색으로 마스크 (예: 주황 계열)
mask = (a[:,:,0] > 200) & (a[:,:,1] > 80) & (a[:,:,1] < 200) & (a[:,:,2] < 110)
ys, xs = np.nonzero(mask)
w, h = xs.max() - xs.min() + 1, ys.max() - ys.min() + 1
print(w, h, w / h)
결과가 606 341 1.777 이었다. 원본은 1024 / 500 = 2.048 이다. 비율이 다르면 어딘가 잘렸다는 뜻이다.
세로가 꽉 찼다고 보고 배율을 역산하면 크롭량이 나온다.
세로 배율 341 / 500 = 0.682
원본 폭의 표시값 1024 × 0.682 = 698px
실제 카드 폭 = 606px
잘린 폭(표시) 698 - 606 = 92px
잘린 폭(원본) 92 / 0.682 = 135px → 한쪽 68px
그래서 여백은 두 개다
설계할 때 보는 값과 사용자가 보는 값이 다르다.
| 원본(1024×500) | 화면에 보이는 값 | |
|---|---|---|
| 왼쪽 여백 80 으로 잡았을 때 | 80 | 12 |
| 왼쪽 여백 152 로 잡았을 때 | 152 | 84 |
첫 줄이 문제의 정체다. 원본에서 80px 은 7.8% 로 좁지 않아 보이는데, 잘리고 나면 12px 만 남아 글자가 벽에 붙는다. “디자인 파일에서 괜찮아 보이는 여백”이 곧 “화면에서 괜찮은 여백”이 아니다.
안전 영역
지금까지 확인된 크롭을 합치면 이렇다.
← 68 → ← 68 →
┌────────────────────────────────────────────────┐
│┊ ┊│ ↑
│┊ 읽혀야 하는 것은 이 안쪽 ┊│ | 세로는
│┊ ┊│ | 잘리지 않는 자리도
│┊ ┊│ | 있지만 크롭하는
│┊ ┊│ ↓ 자리도 있다
└────────────────────────────────────────────────┘
↑ 잘림 잘림 ↑
- 좌우 68px 은 없는 셈 친다. 검색 결과 카드에서 실측한 값이다.
- 위아래도 안심할 수 없다. 자리에 따라 더 납작하게 쓰는 경우가 있어, 위아래 100px 정도는 잘려도 되게 잡아 두면 마음이 편하다.
- 모서리는 둥글게 깎인다. 반지름 48px 짜리 원호가 네 귀퉁이를 먹는다고 보고 그 안에 아무것도 두지 않는다.
결론적으로 글자는 사방 150px 안쪽에 두면 어느 자리에서도 안전하다.
잘려도 되는 것과 안 되는 것을 가른다
여백을 150px 로 잡으면 그림이 휑해지기 쉽다. 여기서 갈라야 할 것은 “읽혀야 하는 것”과 “분위기만 내는 것”이다.
- 글자와 로고/아이콘의 실루엣 — 잘리면 안 된다. 안전 영역 안.
- 배경 원, 그라디언트, 잔상 같은 장식 — 잘려도 그만이다. 오히려 일부러 화면 밖으로 흘려보내면 여백을 지키면서도 그림이 비어 보이지 않는다.
이 구분을 하고 나면 “아이콘을 키우면 여백이 줄어든다”는 딜레마가 사라진다. 아이콘 뒤의 후광은 캔버스 밖으로 내보내고, 아이콘의 흰 획만 안전 영역 안에 두면 된다.
검증은 눈이 아니라 픽셀로
여백은 눈대중이 특히 안 통하는 종류의 값이다. 렌더한 PNG 에서 콘텐츠의 바운딩 박스를 직접 재는 편이 빠르고 확실하다.
from PIL import Image
import numpy as np
a = np.asarray(Image.open("feature.png").convert("RGB")).astype(int)
# 흰 글자만: 세 채널이 고르게 밝은 픽셀
ink = (a[:,:,2] > 200) & (a.max(axis=2) - a.min(axis=2) < 40)
ys, xs = np.nonzero(ink)
print(f"좌 {xs.min()} 우 {a.shape[1]-1-xs.max()} 상 {ys.min()} 하 {a.shape[0]-1-ys.max()}")
크롭 시나리오도 같은 마스크로 바로 검사할 수 있다. “위아래 100px 을 잘라도 잉크를 잃지 않는가”는 ink[:100,:].sum() + ink[-100:,:].sum() == 0 한 줄이다.
덤 — 같은 x 를 줬는데 줄이 안 맞는다
SVG 로 만든다면 하나 더 있다. <text> 의 x 는 글자가 실제로 찍히는 자리가 아니라 앞의 사이드베어링까지 포함한 자리다. 그래서 크기가 다른 줄에 같은 x 를 주면 큰 글자일수록 오른쪽으로 밀려 보인다.
한 글꼴에서 잰 값이다.
| 글자 크기 | 앞 여백 |
|---|---|
| 100px | 5.0px |
| 32px | 1.9px |
| 26px | 1.3px |
비율로 환산하면 5~6% 쯤이지만, 이 비율을 공식으로 박아두면 안 된다. 앞 여백은 크기뿐 아니라 첫 글자와 굵기에 따라 달라진다 — 같은 26px 에서도 글자에 따라 1.25px 과 1.75px 로 갈렸다. 줄마다 x 를 다르게 주고, 문구를 바꿨으면 다시 렌더해서 재는 것 말고는 방법이 없다.
언어별로 그림이 갈리면 좌표도 갈린다
다국어 등록정보라면 언어마다 그래픽을 따로 만들게 되는데, 이때 좌표를 복사하면 안 된다. 라틴 글자와 한글은 앞 여백이 다르고 방향도 일정하지 않아서, 같은 x 를 주면 한쪽이 튀어나온다. 색·크기·구도는 공유하되 x 는 각자 재야 한다.
한 가지 더 — 어느 줄이 가장 긴지가 언어마다 뒤집힌다. 한국어에서는 부제가 가장 길었는데 영문으로 옮기니 제목이 가장 길어졌고, 문구를 한 번 더 다듬자 다시 부제가 길어졌다. “가장 긴 줄이 아이콘을 물지 않는가”는 문구를 고칠 때마다 세 줄을 다 재서 판단해야 한다.
정리
- 피처 그래픽은 1024×500 으로 올리지만 좌우 68px 은 잘려서 안 보인다. 실측값이다.
- 글자는 사방 150px 안쪽에 둔다. 장식은 오히려 캔버스 밖으로 흘려보낸다.
- 여백·정렬은 렌더한 PNG 의 픽셀로 검증한다. 디자인 파일의 숫자를 믿으면 안 된다.
- SVG 의
x는 사이드베어링을 포함한다. 줄마다 다르게 주고, 공식 대신 실측한다.