Skip to content

開発の落とし穴 #1:ICO ファイルは一見問題なさそう——BMP フレームを調べるまでは

2026-06-03

Tags: Windows · 開発の落とし穴


これはストア認定の恐怖体験談ではありません。もっと静かな種類の落とし穴——純粋な好奇心から足を踏み入れた話です。

私は長年、.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 コンバーターは次のように動作します:

  1. 256×256 の PNG を受け取り、必要な各サイズ(16、32、48 など)にダウンスケールする
  2. 256×256 フレームは PNG として保存する
  3. 小さいフレームは 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×256PNG ✓
ファイルエクスプローラー (大/中)48×48BMP ✗
タイトルバー / 小アイコン16×16BMP ✗
Alt+Tab スイッチャー32×32BMP ✗

つまり、アプリのアイコンはデスクトップ上では完璧に見えるのに、タイトルバーやタスクスイッチャーでは謎の「にじみ」や透明度の崩れが発生するのです。ほとんどの人は 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 分の価値はある

この記事は開発の落とし穴シリーズの一部です。