我試圖用C#編程方式在PNG文件中創建一個高質量圖標(表示:suitable for Win Vista/7/8),以用作快捷方式圖標。由於Bitmap.GetHIcon()函數不支持這些圖標,並且我想避免外部依賴項或庫,所以我正在使用稍微修改過的ICO編寫器,我發現它的編號爲here on SO。 我有工作代碼,但我遇到了一些小故障,Windows顯示這些圖標的方式。 相關的代碼是:以編程方式創建高質量的ico文件
// 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();
}
這個編譯和工作,但有一個問題。 Windows錯誤地在快捷方式上顯示圖標。我也以編程方式執行此操作,但即使手動執行(通過文件屬性,更改圖標)也會出現此問題。問題是該圖標被切斷(圖像本身正確顯示)。它取決於圖像,但通常只顯示實際圖標的20%左右。如果我在像XNView這樣的圖像查看器中打開文件,它將顯示完全正確的圖像,但MS Paint不會。 我做了這張截圖,用正確顯示圖標一起進行比較
我懷疑錯誤在於ICO節省的方法,但比較它們正常顯示感染控制主任在十六進制編輯器,頭後仍得到正確書寫,但PNG圖像部分本身seeems不同。有沒有人有想法?我也歡迎更好的,不太冒險的解決方案。
在閱讀它的長度之前,您是否嘗試過沖洗「FS」? –
我發佈了編寫多圖像ICO文件的代碼[在此答案](http://stackoverflow.com/a/29502697/24874)。 –