C语言读取 .ico 文件并显示数据

原来是想做光标编辑器,自己把绘图板的内容导出为光标格式

鼠标指针文件格式解析------Windows(一) (qq.com)

代码来源自

Icons | Microsoft Learn

鄙人又补充些变量可以运行微软的代码

简单代码如下

cpp 复制代码
#include <stdio.h>
#include <windows.h>
//掩码图,其中有XOR是用一个bit 0表示黑,1表示白,即一个字节对应八个像素
typedef struct
{
	BITMAPINFOHEADER   icHeader;      // DIB header
	RGBQUAD         icColors[1];   // Color table
	BYTE            icXOR[1];      // DIB bits for XOR mask
	BYTE            icAND[1];      // DIB bits for AND mask
} ICONIMAGE, *LPICONIMAGE;
// 一个ICON 文件有多个图片,是因为不同机器上识别不同格式图片,这里是紧随ICON文件头之后的图片信息结构体
typedef struct
{
	BYTE        bWidth;          // Width, in pixels, of the image
	BYTE        bHeight;         // Height, in pixels, of the image
	BYTE        bColorCount;     // Number of colors in image (0 if >=8bpp)
	BYTE        bReserved;       // Reserved ( must be 0)
	WORD        wPlanes;         // Color Planes
	WORD        wBitCount;       // Bits per pixel
	DWORD       dwBytesInRes;    // How many bytes in this resource?
	DWORD       dwImageOffset;   // Where in the file is this image?
} ICONDIRENTRY, *LPICONDIRENTRY;


// ICON 文件头
typedef struct
{
	WORD           idReserved;   // Reserved (must be 0)
	WORD           idType;       // Resource Type (1 for icons)
	WORD           idCount;      // How many images?
	ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
} ICONDIR, *LPICONDIR;




void showIcon(LPICONDIR pIconDir,LPICONDIRENTRY pIconDirEntry,LPICONIMAGE lpIconImage){
	printf("%0x\n",pIconDir->idReserved);
	printf("%0x\n",pIconDir->idType);
	printf("%0x\n",pIconDir->idCount);
	printf("pIconDir\n");
	
	printf("%0x\n",pIconDirEntry->bHeight);
	printf("%0x\n",pIconDirEntry->bWidth);
	printf("%0x\n",pIconDirEntry->bColorCount);
	printf("%0x\n",pIconDirEntry->bReserved);
	printf("%0x\n",pIconDirEntry->wPlanes);
	printf("%0x\n",pIconDirEntry->wBitCount);
	printf("%ld\n",pIconDirEntry->dwBytesInRes);
	printf("%ld\n",pIconDirEntry->dwImageOffset);
	
} 

int main()
{
	LPICONDIR pIconDir;							// 用于记录一个完整的ICON 数据头
//	https://blog.csdn.net/jeanphorn/article/details/44982273
	HANDLE hFile=  CreateFile("1.ico",GENERIC_READ,
	                          FILE_SHARE_READ,
	                          NULL,
	                          OPEN_EXISTING,        //打开已存在的文件
	                          FILE_ATTRIBUTE_NORMAL,
	                          NULL);
	DWORD dwBytesRead;								// 要读取的字节数,DROWD 就是 unsigned _long32 ctrl+鼠标左键可查
	// We need an ICONDIR to hold the data
	pIconDir = (LPICONDIR)malloc( sizeof( ICONDIR ) );
// Read the Reserved word
	dwBytesRead=1;											
	ReadFile( hFile, &(pIconDir->idReserved), sizeof( WORD ), &dwBytesRead, NULL );
// Read the Type word - make sure it is 1 for icons
	dwBytesRead=1;
	ReadFile( hFile, &(pIconDir->idType), sizeof( WORD ), &dwBytesRead, NULL );
// Read the count - how many images in this file?
	dwBytesRead=1;						// deByteRead=1 是指读的 1个 WORD ,就是读取一个字,这里对应读取两个字节因为unsigned short是两个字节 
	ReadFile( hFile, &(pIconDir->idCount), sizeof( WORD ), &dwBytesRead, NULL );
// Reallocate IconDir so that idEntries has enough room for idCount elements
	pIconDir = (LPICONDIR)realloc( pIconDir, ( sizeof( WORD ) * 3 ) +
	                    ( sizeof( ICONDIRENTRY ) * pIconDir->idCount ) );
// Read the ICONDIRENTRY elements
	ReadFile( hFile, pIconDir->idEntries, pIconDir->idCount * sizeof(ICONDIRENTRY),
	          &dwBytesRead, NULL );
// Loop through and read in each image
	int i;
	LPICONIMAGE pIconImage;
	for(i=0; i<pIconDir->idCount; i++)
	{
		// Allocate memory to hold the image
		pIconImage =(LPICONIMAGE) malloc( pIconDir->idEntries[i].dwBytesInRes );
		// Seek to the location in the file that has the image
		SetFilePointer( hFile, pIconDir->idEntries[i].dwImageOffset,
		                NULL, FILE_BEGIN );
		// Read the image data
		ReadFile( hFile, pIconImage, pIconDir->idEntries[i].dwBytesInRes,
		          &dwBytesRead, NULL );
		// Here, pIconImage is an ICONIMAGE structure. Party on it :)
		
		//显示读取的数据信息 
		showIcon(pIconDir,&pIconDir->idEntries[i],pIconImage);
		
		// Then, free the associated memory
		free( pIconImage );
	}
// Clean up the ICONDIR memory
	free( pIconDir );
}
相关推荐
奋斗的小花生44 分钟前
c++ 多态性
开发语言·c++
魔道不误砍柴功1 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
闲晨1 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程1 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
Chrikk2 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*2 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue2 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man2 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
萧鼎4 小时前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
学地理的小胖砸4 小时前
【一些关于Python的信息和帮助】
开发语言·python