8

ショートカット アイコンとして使用するために、C# でプログラムによって PNG ファイルから高品質のアイコン (意味: Win Vista/7/8 に適したもの)を作成しようとしています。Bitmap.GetHIcon() 関数はこれらの種類のアイコンをサポートしていないため、外部の依存関係やライブラリを避けたいので、現在SO で見つけたわずかに変更された ICO ライターを使用しています。動作するコードはありますが、Windows がこれらのアイコンを表示する方法に問題があります。関連するコードは次のとおりです。

// ImageFile contains the path to PNG file
public static String IcoFromImageFile(String ImageFile) {
    //...       
    Image iconfile = Image.FromFile(ImageFile);

    //Returns a correctly resized Bitmap        
    Bitmap bm = ResizeImage(256,256,iconfile);                
    SaveAsIcon(bm, NewIconFile);

    return NewIconFile;

}        

// From: https://stackoverflow.com/a/11448060/368354
public static 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
    // Set to 0 for 256 px width/height
    FS.WriteByte(0);
    FS.WriteByte(0);
    // Palette
    FS.WriteByte(0);
    // Reserved
    FS.WriteByte(0);
    // Number of color planes
    FS.WriteByte(1); 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, System.Drawing.Imaging.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();
}

これはコンパイルして動作しますが、1 つの問題があります。Windows では、ショートカットのアイコンが正しく表示されません。これもプログラムで行いますが、手動で行っても(ファイルのプロパティ、アイコンの変更を介して)発生します。問題は、アイコンが切れていることです (画像自体は正しく表示されます)。画像にもよりますが、通常は実際のアイコンの 20% 程度しか表示されません。XNView などの画像ビューアでファイルを開くと、完全に正しく表示されますが、MS ペイントでは表示されません。このスクリーンショットと、比較用に正しく表示されたアイコンを作成しました

ここに画像の説明を入力

エラーはICOの保存方法にあるのではないかと思いますが、Hexエディタで通常表示されているICOと比較しても、ヘッダーは正しく書かれていますが、PNG画像部分自体が違うようです。誰かアイデアはありますか?私はまた、ハックの少ない、より優れたソリューションを歓迎します。

4

1 に答える 1