gpt4 book ai didi

c# - 在 C# 中获取文件和文件夹的透明外壳图标

转载 作者:可可西里 更新时间:2023-11-01 09:25:28 24 4
gpt4 key购买 nike

我目前正在开发一个小型库,使您能够从文件和文件夹中获取图标。现在,我不在乎它是否只适用于 win8+(因为那是我要使用它的地方),但是,我遇到了一个关于透明度的小问题。如果您看一下下图:

Differences

我生成的(从我的库中)在左边,Windows 资源管理器在右边。
现在,您可能会看到,首先我生成的右上角有 2 条黑线,其次,背景颜色有所不同。所以我想知道的是这个;有没有办法获得与 Windows 资源管理器使用的完全相同的图像,还是我只是做错了?

我的代码(为了简短起见,结构/外部等除外)如下,整个代码 here .

public static class Icon
{
public static Image GetIcon(string fileName, int size)
{
IShellItem shellItem;
Shell32.SHCreateItemFromParsingName(fileName, IntPtr.Zero, Shell32.IShellItem_GUID, out shellItem);

IntPtr hbitmap;
((IShellItemImageFactory)shellItem).GetImage(new SIZE(size, size), 0x0, out hbitmap);

// get the info about the HBITMAP inside the IPictureDisp
DIBSECTION dibsection = new DIBSECTION();
Gdi32.GetObjectDIBSection(hbitmap, Marshal.SizeOf(dibsection), ref dibsection);
int width = dibsection.dsBm.bmWidth;
int height = dibsection.dsBm.bmHeight;

// zero out the RGB values for all pixels with A == 0
// (AlphaBlend expects them to all be zero)
for (int i = 0; i < dibsection.dsBmih.biWidth * dibsection.dsBmih.biHeight; i++)
{
IntPtr ptr = dibsection.dsBm.bmBits + (i * Marshal.SizeOf(typeof(RGBQUAD)));
var rgbquad = (RGBQUAD)Marshal.PtrToStructure(ptr, typeof(RGBQUAD));
if (rgbquad.rgbReserved == 0)
{
rgbquad.rgbBlue = 0;
rgbquad.rgbGreen = 0;
rgbquad.rgbRed = 0;
}
else
{
;
}
Marshal.StructureToPtr(rgbquad, ptr, false);
}

// create the destination Bitmap object
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);

// get the HDCs and select the HBITMAP
Graphics graphics = Graphics.FromImage(bitmap);

IntPtr hdcDest = graphics.GetHdc();
IntPtr hdcSrc = Gdi32.CreateCompatibleDC(hdcDest);
IntPtr hobjOriginal = Gdi32.SelectObject(hdcSrc, hbitmap);

// render the bitmap using AlphaBlend
BLENDFUNCTION blendfunction = new BLENDFUNCTION(BLENDFUNCTION.AC_SRC_OVER, 0, 0xFF, BLENDFUNCTION.AC_SRC_ALPHA);
Gdi32.AlphaBlend(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, width, height, blendfunction);

// clean up
Gdi32.SelectObject(hdcSrc, hobjOriginal);
Gdi32.DeleteDC(hdcSrc);
graphics.ReleaseHdc(hdcDest);
graphics.Dispose();
Gdi32.DeleteObject(hbitmap);

return bitmap;
}
}

最佳答案

似乎逐像素复制是解决方案。以下似乎与资源管理器一样完美像素。

    public static Image GetIcon(string fileName, int size)
{
IShellItem shellItem;
Shell32.SHCreateItemFromParsingName(fileName, IntPtr.Zero, Shell32.IShellItem_GUID, out shellItem);

IntPtr hbitmap;
((IShellItemImageFactory)shellItem).GetImage(new SIZE(size, size), 0x0, out hbitmap);

// get the info about the HBITMAP inside the IPictureDisp
DIBSECTION dibsection = new DIBSECTION();
Gdi32.GetObjectDIBSection(hbitmap, Marshal.SizeOf(dibsection), ref dibsection);
int width = dibsection.dsBm.bmWidth;
int height = dibsection.dsBm.bmHeight;

// create the destination Bitmap object
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);

for (int x = 0; x < dibsection.dsBmih.biWidth; x++)
{
for (int y = 0; y < dibsection.dsBmih.biHeight; y++)
{
int i = y * dibsection.dsBmih.biWidth + x;
IntPtr ptr = dibsection.dsBm.bmBits + (i * Marshal.SizeOf(typeof(RGBQUAD)));
var rgbquad = (RGBQUAD)Marshal.PtrToStructure(ptr, typeof(RGBQUAD));

if (rgbquad.rgbReserved != 0)
bitmap.SetPixel(x, y, Color.FromArgb(rgbquad.rgbReserved, rgbquad.rgbRed, rgbquad.rgbGreen, rgbquad.rgbBlue));
}
}

Gdi32.DeleteObject(hbitmap);

return bitmap;
}

关于c# - 在 C# 中获取文件和文件夹的透明外壳图标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13369213/

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