Extrahieren Sie eine bestimmte Symbolebene aus der Datei und speichern Sie sie als ICO-Datei mit Transparenz.

Wie der Titel der Frage besagt, versuche ich, eine bestimmte Symbolebene aus der Datei zu extrahieren und sie dann als ICO-Datei mit Transparenz zu speichern (wie es das Quellensymbol hat).

Es gibt viele Fragen im Zusammenhang mit der Symbolextraktion, aber dies ist spezifisch für den folgenden Code, den ich mit der Verwendung von @ anwend SHDefExtractIcon Funktion.

Das Problem, das ich habe, ist, dass die Farben der generierten .ico-Datei falsch sind, es hat eine Art halbe und schreckliche Transparenz erzeugt, auf der anderen Seite ist die generierte .png-Datei perfekt gespeichert.

Dies ist die resultierende PNG-Datei:

Dies ist die resultierende ICO-Datei:

Ist dies eine Einschränkung der Windows-API, oder mache ich etwas falsch?

C #:

[DllImport("Shell32.dll", SetLastError = false)]
public static extern int SHDefExtractIcon(string iconFile, int iconIndex, uint flags, ref IntPtr hiconLarge, ref IntPtr hiconSmall, uint iconSize);

IntPtr hiconLarge = default(IntPtr);
SHDefExtractIcon("C:\\file.exe", 0, 0, hiconLarge, null, 256);
// ToDO: Handle HRESULT.

Icon ico = Icon.FromHandle(hiconLarge);
Bitmap bmp = ico.ToBitmap();

// Save as .png with transparency. success.
bmp.Save("C:\\ico.png", ImageFormat.Png);

// 1st intent: Save as .ico with transparency. failure. 
//' Transparency is ok but it generates a false icon, it's .png with modified extension to .ico.
bmp.Save("C:\\ico1.ico", ImageFormat.Icon);

// 2nd intent: Save as .ico with transparency. failure. Wrong transparency.
using (MemoryStream ms = new MemoryStream()) {
    ico.Save(ms);
    using (FileStream fs = new FileStream("C:\\ico2.ico", FileMode.CreateNew)) {
        ms.WriteTo(fs);
    }
    // ToDO: Destroy hiconLarge here with DestroyIcon function.
}

VB.NET:

Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices

<DllImport("Shell32.dll", SetLastError:=False)>
Public Shared Function SHDefExtractIcon(ByVal iconFile As String,
                                        ByVal iconIndex As Integer,
                                        ByVal flags As UInteger,
                                        ByRef hiconLarge As IntPtr,
                                        ByRef hiconSmall As IntPtr,
                                        ByVal iconSize As UInteger
) As Integer
End Function


    Dim hiconLarge As IntPtr
    SHDefExtractIcon("C:\file.exe", 0, 0, hiconLarge, Nothing, 256)
    ' ToDO: Handle HRESULT.

    Dim ico As Icon = Icon.FromHandle(hiconLarge)
    Dim bmp As Bitmap = ico.ToBitmap()

    ' Save as .png with transparency. success.
    bmp.Save("C:\ico.png", ImageFormat.Png)

    ' 1st intent: Save as .ico with transparency. failure. 
    ' Transparency is ok but it generates a false icon, it's .png with modified extension to .ico.
    bmp.Save("C:\ico1.ico", ImageFormat.Icon)

    ' 2nd intent: Save as .ico with transparency. failure. Wrong transparency.
    Using ms As New MemoryStream
        ico.Save(ms)
        Using fs As New FileStream("C:\ico2.ico", FileMode.CreateNew)
            ms.WriteTo(fs)
        End Using
    End Using

    ' ToDO: Destroy hiconLarge here with DestroyIcon function.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage