如何使用像素缓冲区加载 Windows 图标?
我正在尝试使用像素缓冲区创建一个与 Windows 兼容的图标。 Surface 类加载图像并将其内部保存为无符号 int 数组 (0xRRGGBB)。
我正在尝试创建一个像这样的图标:
Surface m_Test("Data/Interface/CursorTest.png");
HICON result = CreateIconFromResourceEx( (PBYTE)m_Test.GetBuffer(),
m_Test.GetWidth() * m_Test.GetHeight(),
FALSE,
0,
24,
24,
LR_DEFAULTCOLOR
);
但是,结果
始终为NULL
。我在任何地方都找不到 CreateIconFromResourceEx 所需的数据格式。
最终我想从外部文件加载图标,而不使用资源文件。
提前致谢。
编辑:我想通了!最终代码:
// m_Cursors is an array of images coming from an image strip
Pixel* buffer = m_Cursors[i]->GetBuffer();
int width = m_Cursors[i]->GetWidth();
int height = m_Cursors[i]->GetHeight();
HDC dc_andmask = CreateCompatibleDC(dc);
HBITMAP cur_andmask = CreateCompatibleBitmap(dc, width, height);
HBITMAP hOldAndMaskBitmap = (HBITMAP)SelectObject(dc_andmask, cur_andmask);
HDC dc_xormask = CreateCompatibleDC(dc);
HBITMAP cur_xormask = CreateCompatibleBitmap(dc, width, height);
HBITMAP hOldXorMaskBitmap = (HBITMAP)SelectObject(dc_xormask, cur_xormask);
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
Pixel currpix = buffer[x + y * width];
// the images use the alpha channel for transparancy
if ((currpix & 0xFF000000) == 0
{
// transparant
SetPixel(dc_andmask, x, y, RGB(255, 255, 255));
SetPixel(dc_xormask, x, y, RGB(0, 0, 0));
}
else
{
COLORREF curr = RGB(currpix & 0xFF0000 >> 16, currpix & 0x00FF00 >> 8, currpix & 0x0000FF);
// opaque
SetPixel(dc_andmask, x, y, RGB(0, 0, 0));
SetPixel(dc_xormask, x, y, curr);
}
}
}
// i don't know why this has to be done, but it fixes things
// so who cares (b ")b
SelectObject(dc_andmask, hOldAndMaskBitmap);
SelectObject(dc_xormask, hOldXorMaskBitmap);
DeleteObject(dc_xormask);
DeleteObject(dc_andmask);
ICONINFO temp = { FALSE, m_OffsetX[i], m_OffsetY[i], cur_andmask, cur_xormask };
m_CursorIDs[i] = CreateIconIndirect(&temp);
I'm trying to create a Windows-compatible icon using a pixel buffer. The Surface class loads an image and saves it as an unsigned int array internally (0xRRGGBB).
I'm trying to create an icon like so:
Surface m_Test("Data/Interface/CursorTest.png");
HICON result = CreateIconFromResourceEx( (PBYTE)m_Test.GetBuffer(),
m_Test.GetWidth() * m_Test.GetHeight(),
FALSE,
0,
24,
24,
LR_DEFAULTCOLOR
);
However, result
is always NULL
. I can't find anywhere what data format CreateIconFromResourceEx
expects.
Ultimately I want to load an icon from an external file, without using resource files.
Thanks in advance.
EDIT: I figured it out! The final codez:
// m_Cursors is an array of images coming from an image strip
Pixel* buffer = m_Cursors[i]->GetBuffer();
int width = m_Cursors[i]->GetWidth();
int height = m_Cursors[i]->GetHeight();
HDC dc_andmask = CreateCompatibleDC(dc);
HBITMAP cur_andmask = CreateCompatibleBitmap(dc, width, height);
HBITMAP hOldAndMaskBitmap = (HBITMAP)SelectObject(dc_andmask, cur_andmask);
HDC dc_xormask = CreateCompatibleDC(dc);
HBITMAP cur_xormask = CreateCompatibleBitmap(dc, width, height);
HBITMAP hOldXorMaskBitmap = (HBITMAP)SelectObject(dc_xormask, cur_xormask);
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
Pixel currpix = buffer[x + y * width];
// the images use the alpha channel for transparancy
if ((currpix & 0xFF000000) == 0
{
// transparant
SetPixel(dc_andmask, x, y, RGB(255, 255, 255));
SetPixel(dc_xormask, x, y, RGB(0, 0, 0));
}
else
{
COLORREF curr = RGB(currpix & 0xFF0000 >> 16, currpix & 0x00FF00 >> 8, currpix & 0x0000FF);
// opaque
SetPixel(dc_andmask, x, y, RGB(0, 0, 0));
SetPixel(dc_xormask, x, y, curr);
}
}
}
// i don't know why this has to be done, but it fixes things
// so who cares (b ")b
SelectObject(dc_andmask, hOldAndMaskBitmap);
SelectObject(dc_xormask, hOldXorMaskBitmap);
DeleteObject(dc_xormask);
DeleteObject(dc_andmask);
ICONINFO temp = { FALSE, m_OffsetX[i], m_OffsetY[i], cur_andmask, cur_xormask };
m_CursorIDs[i] = CreateIconIndirect(&temp);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用
CreateIcon
如果您想传递 AND 和 XOR 掩码中的原始字节数据。如果您希望能够使用 HBITMAP,则可以使用
CreateIconIndirect
。使用此 API,如果您愿意,您甚至可以创建带有 Alpha 通道的图标。Use
CreateIcon
if you want to pass the raw bytes data from the AND and XOR mask.If instead you want to be able to use
HBITMAP
s, you can useCreateIconIndirect
. Using this API, you can can even create icons with an alpha channel if you so desire.看一下这个类,取自 koders.com
它提供了方法
和
Take a look at this class taken from koders.com
It provides methods for
and