2014-01-27 4 views
7

Ich habe PNG-Bilder, die ich in ein Symbol vor der Anzeige konvertieren muss. DieseWie konvertiert man ein Bild in ein Symbol ohne Transparenz zu verlieren?

ist, wie ich es tat:

public Icon ImageToIcon(Image imgTest) 
{ 
    Bitmap bitmap = new Bitmap(imgTest); 
    Icon icoTest; 

    IntPtr iPtr = bitmap.GetHicon(); 
    icoTest = (Icon) Icon.FromHandle(iPtr).Clone(); 

    return icoTest; 
} 

ich verlieren Transparenz nach dies zu tun, alpha transparente Bilder werden nicht wie erwartet wiedergegeben .... kann dies gelöst werden?

Antwort

10

Nein, da ist noch viel mehr. Icons haben eine ziemlich ausgeklügelte interne Struktur, die so optimiert wurde, dass sie auf der Hardware der 80er Jahre vernünftig funktioniert. Ein Symbolbild hat drei Bitmaps, eine für das Symbol, eine monochrome Bitmap, die angibt, welche Teile des Bildes transparent sind und eine andere monochrome Bitmap, die angibt, welche Teile umgekehrt sind. Das Erzeugen dieser monochromen Bitmaps ist ziemlich schmerzhaft, .NET unterstützt sie nicht. Bitmap.GetHicon() versucht es auch nicht. Sie benötigen eine Bibliothek, um die Arbeit für Sie zu erledigen.

Vista gab einige Erleichterung, es begann Symbole zu unterstützen, die ein PNG-Bild enthalten. Sie können es mit Ihrem eigenen Code erstellen. Wie folgt:

public static Icon IconFromImage(Image img) { 
     var ms = new System.IO.MemoryStream(); 
     var bw = new System.IO.BinaryWriter(ms); 
     // Header 
     bw.Write((short)0); // 0 : reserved 
     bw.Write((short)1); // 2 : 1=ico, 2=cur 
     bw.Write((short)1); // 4 : number of images 
     // Image directory 
     var w = img.Width; 
     if (w >= 256) w = 0; 
     bw.Write((byte)w); // 0 : width of image 
     var h = img.Height; 
     if (h >= 256) h = 0; 
     bw.Write((byte)h); // 1 : height of image 
     bw.Write((byte)0); // 2 : number of colors in palette 
     bw.Write((byte)0); // 3 : reserved 
     bw.Write((short)0); // 4 : number of color planes 
     bw.Write((short)0); // 6 : bits per pixel 
     var sizeHere = ms.Position; 
     bw.Write((int)0);  // 8 : image size 
     var start = (int)ms.Position + 4; 
     bw.Write(start);  // 12: offset of image data 
     // Image data 
     img.Save(ms, System.Drawing.Imaging.ImageFormat.Png); 
     var imageSize = (int)ms.Position - start; 
     ms.Seek(sizeHere, System.IO.SeekOrigin.Begin); 
     bw.Write(imageSize); 
     ms.Seek(0, System.IO.SeekOrigin.Begin); 

     // And load it 
     return new Icon(ms); 
    } 

Getestet auf .NET 4.5 und Windows 8.1. Hüten Sie sich vor der Möglichkeit von "Fransen", die Sie auf PNG-Bildern mit Transparenz an den Rändern sehen werden. Das funktioniert nur, wenn das Bild auf einer bekannten Hintergrundfarbe dargestellt wird. Von dem eine Ikone niemals abhängig sein kann. Ein dedizierter Icon-Editor wird immer der einzige wirklich gute Weg sein, um gut aussehende Icons zu bekommen.

Verwandte Themen