- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 IShellItemImageFactory 来提取文件的图标。我能够成功提取它并在对话框中使用SendDlgItemMessage(hDlg,IDC_STATIC2, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hicon);
查看输出:click here
问题是当我使用 GDI+ 将其保存为文件(PNG 格式)时,渐变不保留校正。在下面找到我正在使用的代码。
GdiplusStartupInput gdiplusStartupInput;ULONG_PTR gdiplusToken;GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);Bitmap *h = new Bitmap(256, 256, PixelFormat32bppARGB);Graphics* g = Graphics::FromImage(copy);HDC copyHdc = g->GetHDC();DrawIconEx(copyHdc, 0, 0, hicon, 256, 256, 0, NULL, DI_NORMAL);g->ReleaseHDC(copyHdc);;CLSID encoderClsid;GetEncoderClsid(L"image/png", &encoderClsid);h->Save(L"D:\\mynew.png", &encoderClsid, NULL);GdiplusShutdown(gdiplusToken);
提取文本文件后得到的输出:click here
谁能帮我解决这个问题?
问候,马诺杰
最佳答案
这个主题比较老,但我遇到了同样的问题,并且花了很多时间来寻找一种可以保留 PNG 文件透明度的解决方案。
既然问题可以用Java轻松解决...
sun.awt.shell.ShellFolder sf = sun.awt.shell.ShellFolder.getShellFolder(file);
ImageIcon icon = new ImageIcon(sf.getIcon(true));
FileOutputStream bos = new FileOutputStream("d:\\icons\\icon.png");
ImageIO.write((BufferedImage)icon.getImage(), "PNG", bos);
... 我看了一下JDK源代码。在函数“Java_sun_awt_shell_Win32ShellFolder2_getIconBits”的文件“\jdk\src\windows\native\sun\windows\ShellFolder2.cpp”中,我找到了我需要的有值(value)的提示。
此函数从 HICON 中检索颜色位图并调用 GetDIBits 获取图像数据。绘制图标不是必需的 - 无论如何透明度都会丢失。
非常感谢 JDK 开发人员。
这是我最终得到的代码:
static CLSID g_pngClsid = GUID_NULL;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms533843(v=vs.85).aspx
extern int GetEncoderClsid(const WCHAR* format, CLSID* pClsid);
static HICON getShellIconByIndex(int shilsize, int iImage)
{
IImageListPtr spiml;
SHGetImageList(shilsize, IID_PPV_ARGS(&spiml));
HICON hico;
spiml->GetIcon(iImage, ILD_TRANSPARENT, &hico);
return hico;
}
static HICON getShellIcon(int shilsize, const std::wstring& fname) {
UINT flags = SHGFI_SYSICONINDEX;
SHFILEINFO fi = {0};
HICON hIcon = NULL;
if (SHGetFileInfo(fname.c_str(), 0, &fi, sizeof(fi), flags) != 0) {
hIcon = getShellIconByIndex(shilsize, fi.iIcon);
}
return hIcon;
}
struct BITMAP_AND_BYTES {
Gdiplus::Bitmap* bmp;
int32_t* bytes;
};
static BITMAP_AND_BYTES createAlphaChannelBitmapFromIcon(HICON hIcon) {
// Get the icon info
ICONINFO iconInfo = {0};
GetIconInfo(hIcon, &iconInfo);
// Get the screen DC
HDC dc = GetDC(NULL);
// Get icon size info
BITMAP bm = {0};
GetObject( iconInfo.hbmColor, sizeof( BITMAP ), &bm );
// Set up BITMAPINFO
BITMAPINFO bmi = {0};
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = bm.bmWidth;
bmi.bmiHeader.biHeight = -bm.bmHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
// Extract the color bitmap
int nBits = bm.bmWidth * bm.bmHeight;
int32_t* colorBits = new int32_t[nBits];
GetDIBits(dc, iconInfo.hbmColor, 0, bm.bmHeight, colorBits, &bmi, DIB_RGB_COLORS);
// Check whether the color bitmap has an alpha channel.
// (On my Windows 7, all file icons I tried have an alpha channel.)
BOOL hasAlpha = FALSE;
for (int i = 0; i < nBits; i++) {
if ((colorBits[i] & 0xff000000) != 0) {
hasAlpha = TRUE;
break;
}
}
// If no alpha values available, apply the mask bitmap
if (!hasAlpha) {
// Extract the mask bitmap
int32_t* maskBits = new int32_t[nBits];
GetDIBits(dc, iconInfo.hbmMask, 0, bm.bmHeight, maskBits, &bmi, DIB_RGB_COLORS);
// Copy the mask alphas into the color bits
for (int i = 0; i < nBits; i++) {
if (maskBits[i] == 0) {
colorBits[i] |= 0xff000000;
}
}
delete[] maskBits;
}
// Release DC and GDI bitmaps
ReleaseDC(NULL, dc);
::DeleteObject(iconInfo.hbmColor);
::DeleteObject(iconInfo.hbmMask);
// Create GDI+ Bitmap
Gdiplus::Bitmap* bmp = new Gdiplus::Bitmap(bm.bmWidth, bm.bmHeight, bm.bmWidth*4, PixelFormat32bppARGB, (BYTE*)colorBits);
BITMAP_AND_BYTES ret = {bmp, colorBits};
return ret;
}
static void saveFileIconAsPng(int shilsize, const std::wstring& fname, const std::wstring& pngFile) {
HICON hIcon = getShellIcon(shilsize, fname);
BITMAP_AND_BYTES bbs = createAlphaChannelBitmapFromIcon(hIcon);
IStream* fstrm = NULL;
SHCreateStreamOnFile(pngFile.c_str(), STGM_WRITE|STGM_CREATE, &fstrm);
bbs.bmp->Save(fstrm, &g_pngClsid, NULL);
fstrm->Release();
delete bbs.bmp;
delete[] bbs.bytes;
DestroyIcon(hIcon);
}
调用示例:
GdiplusStartup(...);
GetEncoderClsid(L"image/png", &g_pngClsid);
wstring fname = L"d:\\index.html";
wstring pngFile = L"d:\\icons\\index.html.png";
saveFileIconAsPng(SHIL_JUMBO, fname, pngFile);
GdiplusShutdown(...);
关于c++ - 将 HICON 另存为 png,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1818990/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!