開発の落とし穴 #1:ICO ファイルは一見問題なさそう——BMP フレームを調べるまでは
2026-06-03
これはストア認定の恐怖体験談ではありません。もっと静かな種類の落とし穴——純粋な好奇心から足を踏み入れた話です。
私は長年、.ico ファイルを同じ手抜き方法で作っていました。256×256 の PNG を用意して、適当なオンラインコンバーターに放り込み、出来上がったファイルを受け取るだけ。エクスプローラーでいつも正しく表示されていたので、疑うことなど一度もありませんでした。
ところがある日、ICO アンパックツールを開発中に、他の製品の ICO ファイルをテストしていたら、とんでもないものを見つけてしまいました。
見つけたもの
ICO ファイルはコンテナです。複数の画像を異なるサイズ(16×16、32×32、48×48、64×64、128×128、256×256)で格納でき、Windows はタスクバー、タイトルバー、Alt+Tab、ファイルエクスプローラーといった各コンテキストに応じて適切なサイズを選びます。
私の ICO ファイルでは、すべてのフレームが一見問題なく見えました。しかし詳しく調べてみると:
- 256×256 フレーム(PNG として保存)—— 完璧。アルファチャンネルも正常、エッジも滑らか、アーティファクトもなし。
- それより小さい BMP フレーム—— 透明度が完全に壊れていました。アルファチャンネルが存在しないか、ゴミデータが入っているかのどちらか。半透明ピクセルはベタ塗りブロックになり、奇妙な色のにじみが発生していました。
小さいフレームはまるで 90 年代の粗いクロマキー合成のように見えました。
なぜオンラインコンバーターはこれをやらかすのか
ほとんどの無料 PNG→ICO コンバーターは次のように動作します:
- 256×256 の PNG を受け取り、必要な各サイズ(16、32、48 など)にダウンスケールする
- 256×256 フレームは PNG として保存する
- 小さいフレームは 32 ビット BMP として保存する
しかし、ICO ファイル内の BMP フォーマットは特殊です。BITMAPV5HEADER のような高機能なヘッダーは使わず、標準的な 40 バイトの BITMAPINFOHEADER を使用し、biBitCount を 32 に設定します。各ピクセルの 4 バイト目がアルファチャンネルです。そしてここが重要:カラーピクセルデータ(XOR mask)の後には、レガシー互換性のための 1 ビットモノクロ透明マスク(AND mask)が必須です。さらに、ヘッダーの biHeight はこの AND mask 分を含めて実際の画像高さの 2 倍に設定しなければなりません。
多くのオンラインコンバーターはまさにここで失敗します:
- 32 ビットカラーを宣言しておきながら、各ピクセルのアルファバイト(4 バイト目)に
0x00(完全透明)やランダムなゴミデータを詰め込む - 生成する AND mask がアルファチャンネルデータと完全に同期していない
結果:一見「有効」に見えるファイルが出来上がります。ディレクトリエントリも正しく、サイズも合っていて、エクスプローラーも文句を言いません。しかし Windows が小さいフレームをレンダリングしようとすると、GDI blending が暴走します。謎の後光、実際には透明ではない透明ピクセル、その他のレンダリングアーティファクトが発生します。
なぜ手遅れになるまで気づかないのか
Windows エクスプローラーやほとんどのアプリは、表示に 256×256 の PNG フレームを優先して使います。そちらは無傷なので、アイコンは通常の表示——大きいアイコン表示、プロパティダイアログ、タスクバーのプレビューに至るまで——すべて完璧に見えます。
壊れた BMP フレームが表面化するのは、Windows が特定の小さなサイズにダウンスケールする必要があるときだけです。例えば:
| コンテキスト | 使用サイズ | 使われるフレーム |
|---|---|---|
| ファイルエクスプローラー (超大) | 256×256 | PNG ✓ |
| ファイルエクスプローラー (大/中) | 48×48 | BMP ✗ |
| タイトルバー / 小アイコン | 16×16 | BMP ✗ |
| Alt+Tab スイッチャー | 32×32 | BMP ✗ |
つまり、アプリのアイコンはデスクトップ上では完璧に見えるのに、タイトルバーやタスクスイッチャーでは謎の「にじみ」や透明度の崩れが発生するのです。ほとんどの人は Windows の描画の問題だと思い込んでいます。違います——ICO が原因です。
ICO ファイルの確認方法
ICO ファイル内の全フレームを一覧表示できる無料ツールは数多くあります。以下の点を確認しましょう:
- フレームフォーマット:256px フレームは
PNGと表示されるはずです。小さいフレームはBMPと表示されます。すべてのフレームに PNG を使用することは ICO 仕様上技術的には有効ですが、古い Windows バージョンで互換性の問題が発生する可能性があります。PNG(256px)+ BMP(小さいサイズ)の組み合わせが最も安全な選択です。 - BMP のビット深度:真のアルファチャンネルサポート(半透明ブレンディング)のためには
32 BPPであるべきです。24 BPPと表示されている場合、ピクセル単位のアルファデータが失われています。ICO のレガシー 1 ビット AND mask にフォールバックして基本的な「すべて透明かすべて不透明」の背景クリッピングを行うことはできますが、アンチエイリアスされたエッジ、半透明グラデーション、シャドウはすべて崩れ、醜い固形アーティファクトや太い黒い枠線に変わってしまいます。 - 目視確認:各フレームを個別に読み込んでください。小さいフレームは、ギザギザのエッジやベタ塗りの背景ではなく、適切に滑らかなアルファになっているはずです。
修正方法
選択肢 1:適切なアイコンエディターを使い、コンバーターをテストする
元の PNG から、BMP のアルファチャンネルを正しく処理できる適切なエディターで新しい ICO を作成しましょう。オンラインかオフラインかを問わず、コンバーターを信用する前にテストを実行しましょう。既知の半透明領域(ソフトシャドウやグラデーションなど)を含む PNG から ICO を生成し、すべてのフレームを検査します。BMP フレームのアルファが壊れているコンバーターは安全ではありません。
選択肢 2:PNG のみの ICO(可能な場合)
最近のツールの中には、256×256 だけでなく全フレームに PNG 圧縮を使った ICO ファイルを受け付けるものもあります。これで BMP のアルファ問題を完全に回避できます。ただし、すべての Windows バージョンやアプリケーションで汎用的にサポートされているわけではないので、本番で使う前には必ずテストしてください。
まとめ
- エクスプローラーで ICO が正しく見えても、それで問題ないとは限らない
- 256×256 の PNG フレームは大抵正しいが、それより小さい BMP フレームはすべて壊れている可能性がある
- BMP アルファの破損はほとんどの表示では見えない——タイトルバー、Alt+Tab、その他小アイコンが使われるコンテキストでのみ顕在化する
- オンラインコンバーターを頼る前に、半透明部分を含む PNG でテストすること
- リリースするものには必ず適切なアイコンエディターを使おう——たった 5 分の価値はある
この記事は開発の落とし穴シリーズの一部です。