SOUI IBitmap转换为ICON
作者:互联网
在实际使用中,有的API必须要求HICON。
先上效果,这里的托盘图标是用PNG转换为ICON加载的。
上代码 :
CURSORICON_LoadFromBuf。在SOUI的Res解析代码里。翻了一下MSDN没有找到API从内存里加载为HICON的。所以只有用SOUI里的方法了。如有更好的方法忘不吝赐教。
extern HICON CURSORICON_LoadFromBuf(const BYTE* bits, DWORD filesize, INT width, INT height, BOOL fCursor, UINT loadflags);
extern HICON CURSORICON_LoadFromFile(LPCWSTR filename,
INT width, INT height,
BOOL fCursor, UINT loadflags);
class CRGBA2ICON
{
private:
SArray<IBitmap*> m_pBitmapList;
size_t getBufSize()
{
if (m_pBitmapList.GetCount() == 0)
return 0;
size_t retSize = 6;
for (int i = 0; i < m_pBitmapList.GetCount(); i++)
{
CSize size = m_pBitmapList[i]->Size();
int width = size.cx;
int height = size.cy;
retSize += 16+40;
retSize += height * ((width + 31) / 32 * 32 / 8 + width * 3); //Note 4 bytes alignment
retSize += height * width;//AND MASK
}
return retSize;
}
void writeByte(LPBYTE& data,const int val, const int byte)
{
memcpy(data, (void*)&val, byte);
data += byte;
}
void writeByte(LPBYTE &data, LPCVOID val, const int byte)
{
memcpy(data,val, byte);
data += byte;
}
HICON createHIcon()
{
if (m_pBitmapList.GetCount() == 0)
return nullptr;
{
size_t bufsize = getBufSize();
std::unique_ptr<BYTE> buffer(new BYTE[bufsize]);
LPBYTE buf = buffer.get();
int x, y;
int index = 0;
int Size = 0;
int offset = 6 + m_pBitmapList.GetCount() * 16;
int bpp = 32;
writeByte(buf, 0, 2); //idReserved
writeByte(buf, 1, 2); //idType 1为图标 2为光标
writeByte(buf, m_pBitmapList.GetCount(), 2);//idCount 图像数量
//
int width = 0, height = 0;
//字入所有的头
for (int i = 0; i < m_pBitmapList.GetCount(); i++)
{
CSize size = m_pBitmapList[i]->Size();
width = size.cx;
height = size.cy;
//图像块16字节
writeByte(buf, width, 1); //bWidth
writeByte(buf, height, 1); //bHeight
writeByte(buf, 0, 1); //bColorCount
writeByte(buf, 0, 1); //bReserved
writeByte(buf, 1, 2); //wPlanes
writeByte(buf, bpp, 2); //wBitCount
Size = 40 + height * ((width + 31) / 32 * 32 / 8 + width * 3); //Note 4 bytes alignment
Size += height * width;//AND MASK
writeByte(buf, Size, 4); //dwBytesInRes
writeByte(buf, offset, 4); //dwImageOffset
offset += Size;
}
//写入实际的数据
for (int i = 0; i < m_pBitmapList.GetCount(); i++)
{
CSize size = m_pBitmapList[i]->Size();
width = size.cx;
height = size.cy;
//BMP头40字节
writeByte(buf, 40, 4); //biSize
writeByte(buf, width, 4); //biWidth
writeByte(buf, 2 * height, 4); //biHeight
writeByte(buf, 1, 2); //biPlanes
writeByte(buf, bpp, 2); //biBitCount
writeByte(buf, 0, 4); //biCompression
writeByte(buf, 0, 4); //biSizeImage
writeByte(buf, 0, 4); //biXPelsPerMeter
writeByte(buf, 0, 4); //biYPelsPerMeter
writeByte(buf, 0, 4); //biClrUsed
writeByte(buf, 0, 4); //biClrImportant
unsigned char* data = (unsigned char*)m_pBitmapList[i]->LockPixelBits();
// XOR mask
for (y = height - 1; y >= 0; --y) {
for (x = 0; x < width; ++x) {
index = (y * width + x) * 4;
writeByte(buf,data[index], 1); //Blue
writeByte(buf,data[index + 1], 1); //Green
writeByte(buf,data[index + 2], 1); //Red
writeByte(buf,data[index + 3], 1); //Alpha
}
}
// AND mask
for (y = 0; y < (height * ((width + 31) / 32 * 32 / 8)); ++y) {
writeByte(buf,0, 1);
}
}
/*SStringT appdir;
appdir = SApplication::getSingleton().GetAppDir();
std::ofstream iconfile(SStringT().Format(LR"(%s\testpic\008.icon)", appdir), std::ofstream::binary);
iconfile.write((const char*)buffer.get(), bufsize);*/
return CURSORICON_LoadFromBuf(buffer.get(), bufsize, 0,0, FALSE, LR_DEFAULTSIZE | LR_DEFAULTCOLOR);
}
return nullptr;
}
public:
HICON SaveToHICON()
{
return createHIcon();
}
void AddBitmapToIco(IBitmap* pBitmap)
{
pBitmap->AddRef();
m_pBitmapList.Add(pBitmap);
}
void RemoveAllBitmap()
{
for (int i = 0; i < m_pBitmapList.GetCount(); i++)
{
m_pBitmapList[i]->Release();
}
m_pBitmapList.RemoveAll();
}
~CRGBA2ICON()
{
RemoveAllBitmap();
}
};
标签:IBitmap,SOUI,pBitmapList,height,width,int,writeByte,buf,ICON 来源: https://blog.csdn.net/lovehuanhuan1314/article/details/113791924