gpt4 book ai didi

c# - 从文件中提取特定的图标层,然后将其保存为具有透明度的 .ico 文件

转载 作者:太空狗 更新时间:2023-10-29 22:57:37 26 4
gpt4 key购买 nike

正如问题的标题所说,我正在尝试从文件中提取特定的图标层,然后将其保存为具有透明度的 ico 文件(与源图标一样)。

有很多与图标提取相关的问题,但这是特定于我使用 SHDefExtractIcon 应用的以下代码 功能。

我遇到的问题是生成的 .ico 文件的颜色是错误的,它生成了一种半透明的可怕的透明度,另一方面,生成的 .png 文件完美保存。

这是生成的 PNG 文件:

enter image description here

这是生成的 ICO 文件:

enter image description here

这是 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.

最佳答案

你需要一个工具

没有人能够重现这个问题的原因是它需要一个精心设计的艺术图标。一个简单的图标将使从 ico 到磁盘再到图像的过程顺利进行并保持透明度。我们也不知道你做了什么来获得质量差的图像 - 这里是 JPG,所以某处有图标到 JPG 的转换。

所以,我去寻找显示的图像。 Plixia Google 为我找到的垃圾软件似乎不一样,所以我下载了 JDownloader,它的图标与评论中的图片链接相匹配:

enter image description here

不仅失去了透明度,它看起来很糟糕,它在资源管理器中的 ImageView 也同样糟糕。我们都知道 ICO 文件是一个可以容纳许多图像的容器,但事实证明,Icons are complex critters并且没有用于详细/复杂图像的高质量编码器。

图标库

我找到了大量的 C/C++ 代码来管理/处理图标,但也有一个 NET 库可以为您完成这项工作。关于这个主题的帖子很少,但它们似乎都指向无效链接或商业产品。然而,IconLib from CodeProject似乎做你想做的事。简单看一下创建/绘制图标的源代码,它看起来非常像 C/C++ 代码。

它可用于提取图标并将图标保存到集合中。我忽略了那部分,因为这个问题似乎只对 SHDefExtractIcon 感兴趣。它可能有点过时,你可能想为 NET 4.xxx 重新编译它;但它似乎确实写出了一个高质量的图标。以 SHDefExtractIcon 中的图标开头的代码,将其保存到文件并显示文件版本:

Dim file As String = "C:\Temp\electro crapware\JDownloader2.exe"

Dim hiconLarge As IntPtr
NativeMethods.SHDefExtractIcon(file, 0, 0, hiconLarge, Nothing, 256)

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

' png version
bmp.Save("C:\Temp\electro.png", ImageFormat.Png)

'' simple NET ico save: Doesnt Work! (== low quality image)
'Using fs As New FileStream("C:\Temp\electro.ico", FileMode.OpenOrCreate)
' ico.Save(fs)
'End Using

'' Imports System.Drawing.IconLib
Dim myIcons As New MultiIcon()
Dim sIco As SingleIcon = myIcons.Add("electro")

' create Icon from the PInvoked ico.ToBitmap()
' note that enum only goes "up" to Vista
sIco.CreateFrom(bmp, IconOutputFormat.Vista)
sIco.Save("C:\Temp\electro2.ico")

' now display image from disk ico
Dim bmpX As Bitmap
Using icob As New Icon("C:\Temp\electro2.ico")
bmpX = icob.ToBitmap
End Using
pbIcoB.Image = bmpX

' ToDo: Dispose

结果:

enter image description here enter image description here

您可能会使用 SingleIcon.CreateFromSave 方法来创建您自己的版本,或者使用它来代替 PInvoke。我很想在蛇/蠕虫图像上对其进行测试,因为该背景看起来不仅仅是透明度损失。


资源

Icons在 MSDN 上

IconLib在 CodeProject 上

关于c# - 从文件中提取特定的图标层,然后将其保存为具有透明度的 .ico 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37261353/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com