3

タイルセット画像に基づいて108のアイコンの組み合わせ(標準のWindows .icoファイル)を生成するプログラムを作成する必要があります。

System.Drawing.Bitmapクラスを使用して各組み合わせを作成し、次のように保存します。

Bitmap IconBitmap = new Bitmap(16, 16);
// Some processing, writing different parts of the source tileset
// ...
IconBitmap.Save(Path.Combine(TargetPath, "Icon" + Counter + ".ico"),
                ImageFormat.Icon);

しかし、保存されたファイルは実際にはPNGであることがわかりました。WindowsエクスプローラーもVisualStudioも正しく表示できませんが、GIMPは表示できます。また、16進ビューアーで開くと、次のように表示されます。

00000000  89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52  ‰PNG........IHDR
00000010  00 00 00 10 00 00 00 10 08 06 00 00 00 1F F3 FF  ..............óÿ
00000020  61 00 00 00 01 73 52 47 42 00 AE CE 1C E9 00 00  a....sRGB.®Î.é..
00000030  00 04 67 41 4D 41 00 00 B1 8F 0B FC 61 05 00 00  ..gAMA..±..üa...
00000040  00 09 70 48 59 73 00 00 0E C3 00 00 0E C3 01 C7  ..pHYs...Ã...Ã.Ç
00000050  6F A8 64 00 00 00 15 49 44 41 54 38 4F 63 60 18  o¨d....IDAT8Oc`.
00000060  05 A3 21 30 1A 02 A3 21 00 09 01 00 04 10 00 01  .£!0..£!........
00000070  72 A5 13 76 00 00 00 00 49 45 4E 44 AE 42 60 82  r¥.v....IEND®B`‚

また、.icoの名前を.pngに変更すると、Windowsエクスプローラーで正しく表示できます。

ビットマップで何もしなくても、この結果が得られます(これを使用して直接構築するとnewSave黒いpngが得られます)。

私は何が間違っているのですか?

私もこれを試しましたが、16色のアイコンがひどいものになりましたが、とにかく(ハンドルを使用して)この解決策を避けたいと思います:

Icon NewIcon = Icon.FromHandle(IconBitmap.GetHicon());
FileStream FS = new FileStream(Path.Combine(Target, "Icon" + Counter + ".ico"),
        FileMode.Create);
NewIcon.Save(FS);
4

3 に答える 3

3

私は自分で簡単な回避策を作成しました。記録のためにここに投稿します(私のように迅速な解決策が必要な人に役立つかもしれません)。

これを正解とは認めません。実際のアイコン ライターではありません。PNG形式を使用して、32ビットのARGBビットマップをicoファイルに書き込むだけです(Vista以降で動作します)。

ウィキペディアのICO ファイル形式の記事に基づいており、一部は失敗して再試行されます。

void SaveAsIcon(Bitmap SourceBitmap, string FilePath)
{
    FileStream FS = new FileStream(FilePath, FileMode.Create);
    // ICO header
    FS.WriteByte(0); FS.WriteByte(0);
    FS.WriteByte(1); FS.WriteByte(0);
    FS.WriteByte(1); FS.WriteByte(0);

    // Image size
    FS.WriteByte((byte)SourceBitmap.Width);
    FS.WriteByte((byte)SourceBitmap.Height);
    // Palette
    FS.WriteByte(0);
    // Reserved
    FS.WriteByte(0);
    // Number of color planes
    FS.WriteByte(0); FS.WriteByte(0);
    // Bits per pixel
    FS.WriteByte(32); FS.WriteByte(0);

    // Data size, will be written after the data
    FS.WriteByte(0);
    FS.WriteByte(0);
    FS.WriteByte(0);
    FS.WriteByte(0);

    // Offset to image data, fixed at 22
    FS.WriteByte(22);
    FS.WriteByte(0);
    FS.WriteByte(0);
    FS.WriteByte(0);

    // Writing actual data
    SourceBitmap.Save(FS, ImageFormat.Png);

    // Getting data length (file length minus header)
    long Len = FS.Length - 22;

    // Write it in the correct place
    FS.Seek(14, SeekOrigin.Begin);
    FS.WriteByte((byte)Len);
    FS.WriteByte((byte)(Len >> 8));

    FS.Close();
}
于 2012-07-12T08:44:00.263 に答える
0

確かにImageFormat.Icon、.NETは.icoファイルの書き込みをサポートしておらず、単にPNGデータをダンプするだけなので、あなたが想像するように書き込みには機能しません。

CodeProject(およびこれ)(および別のプロジェクト)にはいくつかのプロジェクトがあり、ファイルを作成でき.icoますが、実際にはそれほど難しくありません。ファイル形式は非常に単純で、BMPおよびPNGデータをサポートしています。

于 2012-07-11T14:32:28.437 に答える