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

04-19 1583阅读

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

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

代码来源自

Icons | Microsoft Learn

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

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

简单代码如下 

#include 
#include 
//掩码图,其中有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; iidCount; 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 );
}
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]