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 );
}
相关推荐
Hanniel6 分钟前
Python 元类(下):进阶与实战建议
开发语言·python
jiayong238 分钟前
海量数据处理技术方案与实现原理
大数据·c#·linq
会编程的土豆10 分钟前
Go interface 底层的 itab 到底是什么
开发语言·后端·golang
千纸鹤の脉搏15 分钟前
多线程的初步了解---进程与线程
java·开发语言·学习·线程
秋田君36 分钟前
Qt 5.12.8 下载与安装教程(附网盘资源)
开发语言·qt
故事和你9140 分钟前
洛谷-【动态规划2】线性状态动态规划4
开发语言·数据结构·c++·算法·动态规划·图论
不吃土豆的马铃薯43 分钟前
Socket 网络编程实战教程
linux·服务器·开发语言·网络·c++·算法
小成202303202651 小时前
从C到C++
开发语言·c++
折哥的程序人生 · 物流技术专研1 小时前
《Java 100 天进阶之路》第39篇:Java泛型方法的定义和使用
java·开发语言·后端·面试·求职招聘
天天进步20151 小时前
Tunnelto 源码解析 #1:从 tunnelto --port 8000 看内网穿透的完整链路
开发语言