ssk@tech:~$ cat play-feature-graphic-crop.md

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 는 사이드베어링을 포함한다. 줄마다 다르게 주고, 공식 대신 실측한다.