アプリアイコンは、1 枚の絵が 36 種のサイズの服を着て回ることだ。5 つのプラットフォーム、16 ピクセルのブラウザタブから 1024 ピクセルのストア提出物まで。アプリアイコンジェネレーターは写真を 1 枚受け取り、カバークロップで正方形に切り、その全ファミリーを 1 つの ZIP で書き出す。プラットフォーム別フォルダに入った 36 個の PNG に、PWA の manifest と iOS アイコンセットの manifest を添える。画像は送信されない。クロップ、リサンプル、ZIP の組み立てはすべてブラウザのキャンバスの上で完結する。
5 プラットフォームの 36 サイズ
内訳は iOS 12、Android 9、Web 5、macOS 6、Windows 4。iOS は 29 ピクセルの設定アイコンから 1024 ピクセルの App Store 提出物まで、その間に 40・58・60・76・80・87・120・152・167・180。Android は 512 ピクセルの Play ストアアイコン、2 つの adaptive icon サイズ(48 と 192)、ldpi の 36 から xxxhdpi の 192 までの 5 段のランチャー密度を扱う。Web は 192 と 512 の PWA の組、180 ピクセルの Safari apple-touch-icon、32 と 16 の 2 つの favicon。macOS は 16・32・128・256・512・1024、Windows は 44・71・150 の 3 枚のタイルに 500 ピクセルのストア画像。プラットフォームの切り替えはグループごとを飛ばすので、Web だけのビルドは 36 個の代わりに 5 個の PNG と manifest をダウンロードする。1 つの目標サイズだけ要るときは、同じカバークロップの規則で 1 回のリサイズをする画像リサイズがある。
4000×3000 の写真から 512 のアイコンへ
目標はすべて正方形なので、長方形の写真はまず正方形にならねば縮小できない。規則はカバークロップ:scale = max(w / iw, h / ih)、w と h は目標、iw と ih は元画像。4000×3000 の写真が 512 の目標に入ると、scale = max(512/4000, 512/3000) = max(0.128, 0.17067) = 0.17067 なので、元画像の正方形の辺は 512/0.17067 = 3000、中央取りで sx = (4000 − 3000)/2 = 500、sy = 0。4:3 の写真は 3000×3000 の中央を渡し、両端 500 ピクセルずつが切られる。縦の写真は上下を切る。max を取るのは意図的:min を取ると写真全体を正方形に収めて四隅に余白が残るが、アイコンに残してはならないのがまさにそれ。画像フォーマット変換は幾何に触れず符号化だけを変える、画像トリミングはクロップだけが要るときに同じ中央正方形の計算を当てはめる。
サイズごとに 1 回のリサンプル、チェーンではない
36 の出力はそれぞれ、元画像から 1 回のキャンバス操作で描かれる。スムージングはオン、品質は high。1024 から 512、さらに 256 と続くチェーンは無い。16 ピクセルの favicon は 1024 の源からの 0.015625 倍の一歩、128 ピクセルの macOS アイコンは 512 からの 0.25 倍の一歩だ。それには目に見える帰結がある。すべてのサイズが同じクロップと同一のリサンプルを共有するため、1024 で確かに読めるディテールはまさに 16 でノイズに変わるディテールであり、32・48・64・128・180 のプレビュー行は、弱いデザインが ZIP になる前に姿を現す場所だ。
ZIP に入るもの
アーカイブには ios/・android/・web/・macos/・windows/ のフォルダに分けた最大 36 個の PNG と、3 つの文書が入る。Web が選ばれていれば manifest.json がある。アプリ名、先頭 12 文字に切った short_name(My Very Long App は My Very Long として報告される)、any maskable 用途の 2 つの PWA アイコン、テーマと背景の #ffffff、display は standalone。iOS が選ばれていれば ios/Contents.json があり、Xcode が期待する 14 項目が 20・29・40・60・76・83.5・1024 ポイントサイズを PNG ファイルに読み替える。README.md はプラットフォーム別のサイズとファイルの表を並べる。ダウンロード名はアプリ名から派生する。英数字以外の文字はすべてダッシュになり、全体が小文字になるため、My Cool App は my-cool-app-icons.zip を産む。末尾の句読点は 2 番目のダッシュになる(my-cool-app--icons.zip)、名前欄が 30 文字で切られる理由の一つだ。PNG は無損失の符号化で、1024 アイコンの重さは絵が決める。ストアや Web の予算でバイトを気にする場合は、画像圧縮が同じピクセルを安い符号化で書き直す場所だ。
アイコンが行く場所:manifest、スプラッシュ、ストア
manifest の 2 つのアイコンはブラウザが実際にインストールに使うもの。192 はインストール画面、512 はスプラッシュと共有カード向け。any maskable 用途は、OS が画像を円やスクワイルにクロップしてもよいという合図であり、安全域がキャンバスの中心およそ 80 % の円である理由がこれだ。主役はその中に置き、周囲の余白はプラットフォームの装飾に渡す。web/ の 32 と 16 は favicon の兄弟、つまり manifest を読む前にブラウザが取りに行くタブのアイコンだ。ファビコンジェネレーターはそのファミリーの残り、複数サイズの ICO、Windows の mstile、そのまま貼れる HTML リンクタグを含む。App Store と Play ストアの項目はレビュアーが最初に見るものなので、1024 と 512 はもう 1 回見る価値のあるサイズだ。
どこでも同じリサイズ計算
カバークロップと 1 回の高品質ダウンサンプルは、サイト全体に現れる小さな計算だ。画像リサイズは 1 つの目標に当てはめ、圧縮はそこから出るピクセルを再符号化し、ファイルサイズコンバータは結果を重さで測る場所。36 個の PNG の ZIP が 1024 マスターがバイトで払う場所であり、16 ピクセルのファイルはほぼ無重量だ。もし問題がクロップ自体にあるなら(主役が隅にいて中央正方形の切り取りが外すなら)、画像クロッピングガイドがリサイズ前にクロップの計算を通す。アイコンは、その計算の最後の産物。1 つの正方形、36 のサイズ、そのすべてに同じ中心。