其他分享
首页 > 其他分享> > SOUI IBitmap转换为ICON

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