Извлеките определенный слой значков из файла, затем сохраните его как файл .ico с прозрачностью
Как говорится в заголовке вопроса, я пытаюсь извлечь из файла определенный слой значков, а затем сохранить его как файл ico с прозрачностью (как у исходного значка).
Есть много вопросов, связанных с извлечением значков, но это относится к следующему коду, который я применяю с использованиемSHDefExtractIcon функция.
У меня проблема в том, что цвета сгенерированного .ico-файла неправильные, он создал своего рода половину и ужасную прозрачность, с другой стороны, сгенерированный .png-файл прекрасно сохранен.
Это результирующий файл PNG:
Это результирующий файл ICO:
Это ограничение Windows API или я что-то не так делаю?
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.