C# 在C中获取文件和文件夹的透明外壳图标#
我目前正在开发一个小型库,它可以让你从文件和文件夹中获取图标。现在,我不在乎它是否只在win8+上工作(因为我将在这里使用它),但是,我遇到了一个关于透明度的小问题。如果您查看下图: 我生成的(从我的库中)在左边,windows资源管理器在右边。C# 在C中获取文件和文件夹的透明外壳图标#,c#,windows,com,pinvoke,explorer,C#,Windows,Com,Pinvoke,Explorer,我目前正在开发一个小型库,它可以让你从文件和文件夹中获取图标。现在,我不在乎它是否只在win8+上工作(因为我将在这里使用它),但是,我遇到了一个关于透明度的小问题。如果您查看下图: 我生成的(从我的库中)在左边,windows资源管理器在右边。 现在,正如您可能看到的,首先,在我生成的一条右上角有两条黑线,其次,背景颜色有差异。所以我想知道的是;难道没有办法获得与windows资源管理器使用的完全相同的图像,或者我只是做错了吗 我的代码(除了结构/外部代码等,简称)如下,全部代码 公共静态类
现在,正如您可能看到的,首先,在我生成的一条右上角有两条黑线,其次,背景颜色有差异。所以我想知道的是;难道没有办法获得与windows资源管理器使用的完全相同的图像,或者我只是做错了吗 我的代码(除了结构/外部代码等,简称)如下,全部代码
公共静态类图标
{
公共静态图像GetIcon(字符串文件名,整数大小)
{
IShellItem外壳项目;
SHCreateItemFromParsingName(文件名,IntPtr.Zero,Shell32.IShellItem_GUID,out shellItem);
IntPtr hbitmap;
((IShellItemImageFactory)shellItem).GetImage(新大小(大小,大小),0x0,输出hbitmap);
//获取IPictureDisp中有关HBITMAP的信息
DIBSECTION DIBSECTION=新的DIBSECTION();
Gdi32.GetObjectDIBSection(hbitmap,Marshal.SizeOf(dibsection),ref dibsection);
int width=dibsection.dsBm.bmWidth;
int height=dibsection.dsBm.bmHeight;
//将A==0的所有像素的RGB值归零
//(AlphaBlend希望它们都为零)
对于(int i=0;i
似乎逐像素复制才是解决方案。下面的图片看起来和explorer的一样完美
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;
}
publicstaticimagegeticon(字符串文件名,int-size)
{
IShellItem外壳项目;
SHCreateItemFromParsingName(文件名,IntPtr.Zero,Shell32.IShellItem_GUID,out shellItem);
IntPtr hbitmap;
((IShellItemImageFactory)shellItem).GetImage(新大小(大小,大小),0x0,输出hbitmap);
//获取IPictureDisp中有关HBITMAP的信息
DIBSECTION DIBSECTION=新的DIBSECTION();
Gdi32.GetObjectDIBSection(hbitmap,Marshal.SizeOf(dibsection),ref dibsection);
int width=dibsection.dsBm.bmWidth;
int height=dibsection.dsBm.bmHeight;
//创建目标位图对象
位图位图=新位图(宽度、高度、像素格式.Format32bppArgb);
对于(int x=0;x
这对我来说不太管用。我已经查找了需要从gdi32.dll
导入的函数和结构,但它们似乎不太正确。例如,dibsection.dsBmih.biWidth
始终为0。您的Gdi32
类中有什么?Gdi32类是一个简单的类,包含直接映射到Gdi32.dll
的内部静态外部方法。
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;
}