Windows/C++ -- 将图标渲染为具有透明度的位图

Posted

技术标签:

【中文标题】Windows/C++ -- 将图标渲染为具有透明度的位图【英文标题】:Windows/C++ -- rendering icon to bitmap with transparency 【发布时间】:2019-07-13 16:08:35 【问题描述】:

我不是任何 GDI 方面的专家。但是几年前我收到了一些代码,这对我很有帮助。但是,它变老了……而且有了新的 windows10 深色主题,它显示出它的缺陷。

我正在渲染一个菜单(在资源管理器菜单插件中)。这是用于生成位图的代码的 sn-p。

我的目标是将此代码转换为保留图标透明度的位图。

(结果 HBITMAP 以 pItem->m_hBitmap 结束)

HICON hIcon;
if ( (iIndex >= 0) && (ExtractIconEx(iconDLLPath, iIndex, NULL, &hIcon, 1) != 0) )

    HDC hdc = CreateIC(L"DISPLAY", NULL, NULL, NULL);
    HDC hdcMem = CreateCompatibleDC(hdc);

    // XP demands 12x12, otherwise use 16x16
    int cx = GetSystemMetrics((m_bUseSmallerIcons) ? SM_CXMENUCHECK : SM_CXSMICON);
    int cy = GetSystemMetrics((m_bUseSmallerIcons) ? SM_CYMENUCHECK : SM_CYSMICON);
    pItem->m_hBitmap = CreateCompatibleBitmap(hdc, cx, cy);
    HBITMAP hBmOld = (HBITMAP) SelectObject(hdcMem, pItem->m_hBitmap);

    // DC:  paint entire mem dc COLOR_MENU so icon looks transparent
    // when painted into context menu having this background color
    HBRUSH hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
    RECT rect;
    rect.left = 0;
    rect.top = 0;
    rect.right = cx;
    rect.bottom = cy;
    FillRect(hdcMem, &rect, hBrush);
    DeleteObject(hBrush);

    // Draw icon transparently, on top of the background color.  Transparent
    // areas will be the background color.
    DrawIconEx(hdcMem, 0, 0, hIcon, cx, cy, 0, 0, DI_NORMAL);

    // Cleanup
    SelectObject(hdcMem, hBmOld);
    DeleteDC(hdc);
    DeleteDC(hdcMem);

    DestroyIcon(hIcon);

我应该删除绘制白色背景的,但是如何放下透明背景?我尝试过的一切都会产生黑色背景。 * 只是去除白色的“填充” * SetBkMode(透明) * 使用主题代码获取菜单颜色...

如何制作具有透明度的适当位图?

【问题讨论】:

DrawIconEx 可能正在以透明的方式完成其工作。但位图不透明。我不知道这里到底发生了什么,你可以在 PNG 文件上绘制透明度,或者使用TransparentBlt 绘制位图... 【参考方案1】:

最终,答案是我没有做错任何事。此菜单是使用 IContextMenu 在 shell 插件中构建的菜单的一部分。

答案 - 实现 IContextMenu2。在这样做的过程中,做一个所有者绘制菜单项。

【讨论】:

以上是关于Windows/C++ -- 将图标渲染为具有透明度的位图的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Xcode 中渲染具有半透明纹理的 3D 模型?

java TrayIcon使用具有透明背景的图像

在 OpenGL 中将粒子渲染为具有透明度的 GL_TRIANGLE_FAN

如何将背景转换为透明? [关闭]

渲染具有透明度的纹理时 OpenGL 不需要的像素

Opengl 透明部分被渲染为黑色