안드로이드를 만들며 10 — 앱 아이콘의 검은 모서리와 크기를 맞추기까지
둥근 타일 이미지를 적응형 아이콘으로 옮기며 검은 모서리, 배경 이음매, 크기 문제를 겪었습니다. 가장자리 픽셀을 복제하고 그림 크기를 측정하는 방식으로 바꿔 변환 스크립트를 저장소에 남겼습니다.
들어가며
앱 아이콘 원본은 검정 배경 위에 보라색 둥근 타일을 얹은 PNG였습니다. 그대로 안드로이드 런처에 넣자 타일 모서리에 검은 부분이 남았습니다. 검은 부분을 잘라 내면 그림이 커졌고, 배경을 다시 만들면 이음매가 보였습니다. 모서리를 정리한 뒤에도 아이콘 크기를 다시 맞춰야 했습니다.
원본에도 둥근 모서리가 있었습니다
안드로이드 8부터 사용하는 적응형 아이콘은 108dp 크기의 앞면과 뒷면으로 이루어집니다. 앱은 두 이미지를 제공하고, 런처는 원이나 스퀴클, 둥근 사각형 등 기기에 맞는 마스크를 씌웁니다.
108dp 중 마스크가 남기는 가운데 영역은 72dp입니다. 바깥쪽은 패럴랙스 같은 효과에 쓰이는 여유 공간이라 잘릴 수 있습니다. 받은 원본은 이미 모서리가 둥글게 처리되어 있었으므로, 런처의 마스크와 원본의 모양을 함께 고려해야 했습니다.
잘라낸 만큼 그림이 커졌습니다
원본의 검은 구석을 그대로 두면 런처 마스크와 타일의 둥근 모서리가 겹쳤습니다. 두 경계 사이에는 검은 초승달 모양이 남았습니다.
처음에는 사방을 타일 반지름만큼 잘라냈습니다. 검은 구석은 없어졌지만 남은 이미지를 다시 전체 크기로 늘리면서 그림까지 확대됐습니다. 사방에서 6.5%를 자르면 그림은 약 15% 커집니다. 원래 안전 구역에 들어 있던 부분이 바깥으로 밀려났습니다.
원본의 모서리와 그라데이션을 재현하려던 시도
두 번째로는 원본을 둥근 사각형으로 자르고 그 아래에 배경 그라데이션을 깔았습니다. 그러나 원본의 모서리는 원호로 만든 둥근 사각형과 달랐습니다.
실제 픽셀을 재니 맨 윗줄(y=0)의 검은 구간은 80px이었습니다. 원호라면 y=40에서 검은 구간이 11px로 줄어야 하는데, 원본에서는 17px이었습니다. 원본은 원호보다 바깥으로 부푼 스퀴클(squircle) 형태였고, 두 곡선 사이에 검은 부분이 남았습니다.
배경색도 예상과 달랐습니다. 단순한 세로 그라데이션으로 생각했지만 위쪽 한가운데는 #AE7CEA, 왼쪽 위 구석은 #9968E7이었습니다. 새로 깐 배경이 구석에서 더 밝아 타일 경계가 윤곽선처럼 드러났습니다.
잘라 낸 자리에 가장자리 픽셀 복제하기
모서리의 곡선과 배경색을 재현하는 대신, 사방을 반지름+2px만큼 잘라내고 그만큼 가장자리 픽셀을 복제해 채웠습니다. 이미지 도구의 extendWith: "copy"를 사용했습니다.
잘라낸 이미지를 확대하지 않으므로 그림의 위치와 크기는 유지됩니다. 채우는 색도 원본 가장자리에서 가져오므로 별도의 배경색을 추정할 필요가 없어졌습니다. 이 방식으로 검은 모서리와 배경의 이음매를 처리했습니다.
38dp는 작고, 66dp는 컸습니다
모서리를 정리한 뒤에는 타일을 72dp로 줄였습니다. 108dp 중 보이는 영역에 타일 전체를 넣으려는 선택이었습니다. 하지만 원본에서 그림이 차지하는 비율은 53%였으므로 실제 그림은 38dp에 불과했습니다. 런처에서는 다른 아이콘보다 작고 흐릿하게 보였습니다.
다음에는 그림의 밝은 화소가 차지하는 최대 반지름을 쟀습니다. 어떤 마스크에서도 남는 지름 66dp 원, 즉 키라인 원에 맞춰 타일 크기를 역산했습니다.
66dp에 맞추니 이번에는 너무 컸습니다. 잘리지는 않았지만 그림이 마스크 가장자리에 닿았고, 옆 아이콘보다 부풀어 보였습니다.
최종 그림 크기는 54dp로 정했습니다. 108dp 판의 절반이며, 보이는 72dp 원 안에서는 사방에 9dp가 남습니다. 처음의 38dp보다 크게 보이면서도 가장자리에 여백을 둘 수 있었습니다.
원본이 바뀌어도 다시 만들 수 있게
원본이 바뀌면 이 크기 조정을 다시 해야 합니다. 변환 과정은 다음 명령으로 실행할 수 있게 남겼습니다.
node brand/app-icon.mjs
이 명령은 원본의 맨 윗줄에서 검은 구간을 세어 반지름을 다시 구합니다. 뒷면 색도 정해 둔 브랜드색 대신 원본 로고의 끝 색을 측정해 사용합니다. 앞면이 불투명하면 뒷면은 런처가 앞면을 움직일 때 드러나므로, 그때 보이는 색을 원본과 맞췄습니다.
마치며
사실 처음 작업한 날의 스크립트는 저장하지 못했습니다. 나중에 리소스 주석이 가리키는 파일을 찾다가 없다는 걸 알았습니다. 이번에는 결과 이미지와 함께 스크립트도 저장소에 넣었습니다.