鼠标指针文件格式解析

这篇具有很好参考价值的文章主要介绍了鼠标指针文件格式解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

鼠标指针文件格式解析

写在前面:2023.2.22更新了ico的图像数据段部分,这个部分写的有一些错误

windows

在介绍鼠标指针文件之前,我们先来介绍一下图标文件。

一般大一点的软件里,都会有一个ico文件,这个图标的分辨率一般来说都较小。且无颜色的部分都为透明状,也就是阿尔法通道值为0。

ico文件格式分析

文件后缀名一般位icon或者ico。

本篇文章主要是以在ico文件头后续加入了bitmap这种图片,而在ico文件头后续加入png等不在讨论的范围内。

ico的文件格式主要包括文件头、图像数据两部分。

文件头struct ICONDIR icondir

这个部分文件头固定6字节,剩下的16字节代表了图像信息,每增加一张图片,这部分增加16字节。

具体结构解释如下:

type
 	ICONDIR = packed record					
    idReserved: SmallInt; // Reserved		保留位,必须为0
	idType: SmallInt; // Resource type		光标资源类型,作为ico时值为1
	idCount: SmallInt; // Image Count		标记了文件中包含的图像数量,与后面的images数量相一致
 end; // 6 bytes
struct ICONDIRENTRY idEntries

剩下的16字节代表了图像的具体数据。

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)						必须为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;

bColorCount; 它被假定的认为等于图像的颜色数量,也就是说:bColorCount = 1 << (wBitCount * wPlanes)

如果 wBitCount * wPlanes大于等于8,则bColorCount为0。

读取完这部分数据后,就可以知道文件中每个图标的大小,颜色位数了,同时直接根据数据段的偏移,读取图像数据段。图像数据的偏移是从文件最开始算起的。

图像数据头段struct BITMAPINFOHEADER bmiHeader

BITMAPINFOHEADER (wingdi.h) - Win32 apps |微软学习 (microsoft.com)

紧接着文件头的就是图像数据头段了,它存放着文件中每个图像宽度、高度、颜色数量、数据段的偏移等信息,大小为40字节。

它是一个数组,每项数据16字节,定义如下:

type def struct tag 
BITMAPINFOHEADER{
    DWORD  biSize;						数据块大小40
    LONG   biWidth;						图像宽度
    LONG   biHeight;					2*图像高度,XOR掩码区和AND掩码区高度之和
    WORD   biPlanes;					指定目标设备的平面数。此值必须设置为 1。
    WORD   biBitCount;					位深度					
    DWORD  biCompression;				这个值没有用到,为0
    DWORD  biSizeImage;					掩码数据区的大小(XOR和AND)
    LONG   biXPelsPerMeter;				定位图的目标设备的水平分辨率(以像素/米为单位)X坐标热点,与Y同为0代表左上角
    LONG   biYPelsPerMeter;				定位图的目标设备的垂直分辨率(以像素/米为单位)Y坐标热点
    DWORD  biClrUsed;					实际使用颜色索引,在ico中值为0
    DWORD  biClrImportant;				重要的颜色索引,在ico中为0
} BITMAPINFOHEADER, *PBITMAPINFOHEADER; 
图像数据段struct IMAGEDATA data

图像数据为多个图像的DIB数据,根据数据头段的偏移来定位。定位后,读取BIH信息。从BIH信息中,判断颜色位数大于8位的,记取XOR调色盘数据(小于8位的不存在XOR调色盘,只包含有一个MASK调色盘)。读取完XOR调色盘后,初始化图像DIB头,然后在文件中读取DIB数据。

ICON图标文件解析 - findumars - 博客园 (cnblogs.com)

上面这句话是来自这篇文章,讲实话,其实没有很懂

没懂不要紧,来讲一下我的理解

接下来的这部分的结构如下,这个部分代表了颜色。

type def struct tag RGBQUAD {
  BYTE  rgbBlue;			蓝
  BYTE  rgbGreen;			绿	
  BYTE  rgbRed;				红
  BYTE  rgbReserved;		保留位,一般为0
} RGBQUAD;

下面的maskline是掩码区。

提问,为什么这里是8个,跟上面的64个不相同的个数呢?

掩码区使用01代表该颜色存不存在,也就是使用00和FF黑白二色表示,可以将其理解为位深度为1的图片,使用1个bit就能代表一个黑或白的颜色,假设FE转成二进制就是11111110,每一个就是8个可以与上面对应,这个也可以解释为什么下面的mask区域还有非00,非FF的。

也就是说掩码区的作用是代表着这个地方的颜色透不透明。

详细参考下图中的第二行,Q代表这个颜色是Q。

最后的mask的部分,可以继续查看这篇文章:

The evolution of the ICO file format, part 2: Now in color! - The Old New Thing (microsoft.com)

至于为什么在介绍鼠标指针文件格式解析时要先介绍ico图标,我会在后续文章中进行揭秘。

最最后的无奖提问环节,计算机是怎么实现图片的透明显示的呢?

答案我会在下一篇中揭晓。(大概,如果能写到的话

以上。

Ani动态光标格式解析

Ani动态光标格式解析 - 孤影对酌 - 博客园 (cnblogs.com)

文件类型关系:

bmp ∈ (ico == cur ) ∈ ani

数据结构:

ani文件结构在010里并没有直接的模板,而是以RIFF为开头标志位的文件,因此也可以使用RIFF模板来分析

本文是在孤影对酌师傅的文章基础上进行了一些备注,以供自己学习和分析

Ani文件中的数据是按区段存放的,区段数据结构如下:

标识符(4字节ASCII),数据长度(一个DWORD),数据

按照此规则来看Ani文件,文件起始12字节(12字节指以下标识符、数据长度和ACON三个部分)可以理解为标准文件头,除数据长度外,其余两个字段不会改变:

0x0000    52 49 46 46    标识符'RIFF'
0x0004    40 4D 00 00    数据长度,指整个文件的大小
0x0008    41 43 4F 4E    'ACON'

标准头之后,就是各个区段了,在孤影对酌师傅的探索中共发现了:‘anih’, ‘rate’, 'seq ', 'LIST’4种区段('seq '区段标识最后一个字符是空格,共4个字符)。

‘anih’

此区段数据长度恒为36,每4字节为一组,另外,数据长度36加上块大小4和名称4共44,里面存储的是一个结构体:

struct _anih
{
    DWORD    dwHeaderSize;     //结构体大小,恒为36
    DWORD    dwNumFrames;      //图像帧数,代表转为gif有多少帧,且该数与LISTchunk数量相等
    DWORD    dwNumSteps;       //播放帧数,当'seq '存在时可能大于dwNumFrames
    DWORD    dwWidth;          //图像宽度
    DWORD    dwHeight;         //图像高度
    DWORD    dwBitCount;       //色彩位数
    DWORD    dwNumPlanes;      //设备平面数
    DWORD    dwDisplayRate;    //显示频率(Time Delay,单位为1/60秒)
    DWORD    dwFlags;          //标志
};

dwFlags的第0位为1时,表示图像帧数据格式为Icon或Cursor,为0表示图像帧数据为位图raw数据,使用_anih结构中的尺寸、色彩深度等信息。

第1位解释为bool型,表示文件是否含有’seq '段。

'seq ’

010显示顺序位**先rate后seq **

此区段为可选段(不一定存在),段内的数据为一个DWORD数组,长度为 “区段数据长度” / sizeof(DWORD)。

0x0000    73 65 71 20    标识符'seq '
0x0004    24 00 00 00    数据长度
0x0008    00 00 00 00    数组元素[0],值为0表示此处显示第0帧图像
0x000C    01 00 00 00    数组元素[1],值为1表示第一帧图像
0x0010    02 00 00 00    [2],第2帧
0x0014    03 00 00 00    [3],第3帧
0x0018    00 00 00 00    [4],第0帧
0x001C    04 00 00 00    ...
0x0020    05 00 00 00
0x0024    01 00 00 00
0x0028    00 00 00 00

此区段存储的是播放顺序,当Ani文件播放时,按照DWORD数组下标递增,依次从此数组中取出图像帧号,再到存储图像帧数据的’LIST’段中获取对应的图像帧进行显示。所以在一次播放中,同一个图像帧可以出现多次。_anih结构中的dwNumSteps即为播放起始数组下标。

此区段不存在时,'LIST’中图像帧的顺序即为播放顺序,_anih结构中的dwNumSteps为播放起始帧号。

‘rate’

此区段为可选段,段内数据为一个DWORD数组,长度为 “区段数据长度” / sizeof(DWORD)。

表示每一帧的播放速率,gif的每一帧都是匀速播放的,rate的存在代表这个播放的速率不一定相同

0x0000    72 61 74 65    标识符'rate'
0x0004    24 00 00 00    数据长度
0x0008    0F 00 00 00    x 1/60秒 = Time Delay
0x000C    0F 00 00 00
0x0010    0F 00 00 00
0x0014    0F 00 00 00
0x0018    46 00 00 00
0x001C    0F 00 00 00
0x0020    0F 00 00 00
0x0024    0F 00 00 00
0x0028    0F 00 00 00

此区段内存储的为播放频率(Time Delay),同样以1/60秒为单位,当’seq '存在时,按相同下标与’seq '中的每个元素相对应,数组大小与’seq '相等。当’seq '不存在时,与’LIST’中图像帧相对应,数组大小等于_anih结构中的dwNumFrames。

‘LIST’

同样拥有12字节“标准头”,探索中发现,此区段内存储的数据有两种可能:

1.Ani文件的名称、作者

2.图像帧数据

当存储名称、作者信息时,格式为:

0x0000    4C 49 53 54    标识符'LIST',前12字节为“标准头”
0x0004    26 00 00 00    数据长度
0x0008    49 4E 46 4F    标识符'INFO'表示此列表为信息列表

0x000C    49 4E 41 4D    标识符'INAM'表示名称
0x0010    0C 00 00 00    数据长度
0x0014    68 65 61 72 74 73 74 69 63 6B 31 00    字符串'heartstick1'

0x0020    49 41 52 54    标识符'IART'表示作者
0x0024    06 00 00 00    数据长度
0x0028    68 75 61 6C 69 00    字符串'huali'

当存储图像帧数据时,格式为:

0x0000    4C 49 53 54    标识符'LIST',前12字节为“标准头”
0x0004    90 11 00 00    数据长度
0x0008    66 72 61 6D    标识符'fram'表明此列表为图像数据帧列表

0x000C    69 63 6F 6E    标识符'icon'标识图像数据帧数据区段
0x0010    BE 08 00 00    数据长度
0x0014    00 00 02 00    图像数据
...       ...            多帧图像

至此,数据结构解析完毕。

此时有一个疑问,在icon的图像数据中,数据块的大小和图片的大小和像素有什么关系呢?

此时的这个图像数据是一个cur的文件格式

我们可以按照ico图标文件来进行分析

cur静态光标文件格式解析

很好,这次是彻底没有模板可以借助了

让我们从零开始分析一个文档吧

看了出题人写的文章,了解到cur文件也是和ico文件同属一宗,但唯一不同的是有一个标志位表明这是一个cur文件

这个标志位是全文档的第三个字节
鼠标指针文件格式解析

唯二一篇可以参考的文章

从Windows动态指针到MacOS动态指针——ANI2GIF - 哔哩哔哩 (bilibili.com)

CURSOR 文件格式解析_jinhaijian的博客-CSDN博客

全称为CURSOR

因此,剩下的部分可以按照ico图标文件进行分析

macOS

从Windows动态指针到MacOS动态指针—— 在Windows上制作指针 - 哔哩哔哩 (bilibili.com)

是xml的形式,后缀名为cape文件

结构如下:

{
    'Author': '',
    'CapeName': '',
    'CapeVersion': 1.0,
    'Cloud': False,
    'Cursors': {
        'com.apple.coregraphics.Arrow': {
            'FrameCount': 1,
            'FrameDuration': 1.0,
            'HotSpotX': 0.0,
            'HotSpotY': 0.0,
            'PointsHigh': 32.0,
            'PointsWide': 32.0,
            'Representations': [b'']
        }
    },
    'HiDPI': False,
    'Identifier': 'local.error404.Unnamed.635739212.539397.A9D5CFB1-558B-46DD-95BB-3E8D6ED022D8.693110507.131993',
    'MinimumVersion': 2.0,
    'Version': 2.0
}

例子

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Author</key>
	<string>小蓝蓝</string>
	<key>CapeName</key>
	<string>蓝蓝的测试图标</string>
	<key>CapeVersion</key>
	<real>1.0</real>
	<key>Cloud</key>
	<false/>
	<key>Cursors</key>
	<dict>
		<key>com.apple.coregraphics.Arrow</key>
		<dict>
			<key>FrameCount</key>
			<integer>34</integer>					#代表帧数
			<key>FrameDuration</key>
			<real>0.1</real>
			<key>HotSpotX</key>						#代表生效的点的位置
			<real>0.0</real>
			<key>HotSpotY</key>
			<real>0.0</real>
			<key>PointsHigh</key>
			<real>32.0</real>						#代表图像大小,32*32
			<key>PointsWide</key>
			<real>32.0</real>
			<key>Representations</key>
			<array>
				<data>
                base64转图片,图片类型为tiff
				</data>
			</array>
		</dict>
		<key>com.apple.coregraphics.IBeam</key>
		<dict>
			<key>FrameCount</key>
			<integer>28</integer>
			<key>FrameDuration</key>
			<real>0.1</real>
			<key>HotSpotX</key>
			<real>0.0</real>
			<key>HotSpotY</key>
			<real>0.0</real>
			<key>PointsHigh</key>
			<real>32.0</real>
			<key>PointsWide</key>
			<real>32.0</real>
			<key>Representations</key>
			<array>
				<data>
                base64转图片,图片类型为tiff
				</data>
			</array>
		</dict>
		<key>com.apple.coregraphics.Move</key>
		<dict>
			<key>FrameCount</key>
			<integer>24</integer>
			<key>FrameDuration</key>
			<real>0.1</real>
			<key>HotSpotX</key>
			<real>0.0</real>
			<key>HotSpotY</key>
			<real>0.0</real>
			<key>PointsHigh</key>
			<real>32.0</real>
			<key>PointsWide</key>
			<real>32.0</real>
			<key>Representations</key>
			<array>
				<data>
                base64转图片,图片类型为tiff
				</data>
			</array>
		</dict>
		<key>com.apple.cursor.17</key>
		<dict>
			<key>FrameCount</key>
			<integer>52</integer>
			<key>FrameDuration</key>
			<real>0.1</real>
			<key>HotSpotX</key>
			<real>0.0</real>
			<key>HotSpotY</key>
			<real>0.0</real>
			<key>PointsHigh</key>
			<real>32.0</real>
			<key>PointsWide</key>
			<real>32.0</real>
			<key>Representations</key>
			<array>
				<data>
                base64转图片,图片类型为tiff
				</data>
			</array>
		</dict>
		<key>com.apple.cursor.18</key>
		<dict>
			<key>FrameCount</key>
			<integer>31</integer>
			<key>FrameDuration</key>
			<real>0.1</real>
			<key>HotSpotX</key>
			<real>0.0</real>
			<key>HotSpotY</key>
			<real>0.0</real>
			<key>PointsHigh</key>
			<real>32.0</real>
			<key>PointsWide</key>
			<real>32.0</real>
			<key>Representations</key>
			<array>
				<data>
                base64转图片,图片类型为tiff
				</data>
			</array>
		</dict>
	</dict>
	<key>HiDPI</key>
	<false/>
	<key>Identifier</key>
	<string>local.小蓝蓝.蓝蓝的测试图标.1673433937.428604.949CA744-8B80-4D9F-A8F6-7DA1877E517E.1673433937.428639</string>
	<key>MinimumVersion</key>
	<real>2.0</real>
	<key>Version</key>
	<real>2.0</real>
</dict>
</plist>

Linux

文档好像很复杂捏

挖巨坑文章来源地址https://www.toymoban.com/news/detail-490580.html

到了这里,关于鼠标指针文件格式解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ELF文件格式解析

       ELF(Executable and Linkable Format) 即可执行可链接文件格式,是目前操作系统上最常见的可执行文件格式。不同系统的目标文件不一样,Windows是PE(Portable Executable),linux是ELF(Executable Linkable Format),它们都是COFF(Common file format)格式的变种。       ELF格式的目标文件和可执

    2023年04月16日
    浏览(38)
  • MP4文件格式解析

    读完本文你将收获: 知道如何读取一个mp4文件的基本信息。 知道如何从一个mp4文件中分离对应的视频数据或者音频数据的基本原理。 知道播放一个mp4文件时seek到指定时间,如何在mp4文件中查找到对应的媒体数据。 一个 mp4 文件通常由音频和视频两部分组成(当然有些还包含

    2023年04月26日
    浏览(53)
  • 【音视频 | AAC】AAC格式音频文件解析

    😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭 🤣本文内容🤣:🍭介绍AAC格式音频文件解析🍭 😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭 本文未经允许,不得转发!!

    2024年02月04日
    浏览(55)
  • C++文件格式深度解析:从底层结构到关键特性

    在计算机科学中,文件格式是存储在某种存储媒介上的文件的特定编码方式。每种文件格式都有特定的标准或规范,定义了文件中数据的组织方式。理解文件格式的基本概念对于编程,尤其是使用C++进行文件操作,是非常重要的。 在C++中,文件是以字节流的形式存储在存储设

    2024年02月06日
    浏览(82)
  • 【已解决】 selenium解析页面链接打包为jar文件后报错element.getAttribute()处空指针NullPointerException

             在java中使用selenium+Chrome实现爬虫程序时,对爬取到的链接进行解析,在本地Windows系统下解析完全没有问题,但是导出jar文件后,放在centos系统下运行,可以解析到链接的文本,但是使用ement.getAttribute()获取链接等其它属性时报错,不管是什么属性,都提示ement

    2024年02月12日
    浏览(36)
  • nodejs实现解析chm文件列表,无需转换为PDF文件格式,在线预览chm文件以及目录,不依赖任何网页端插件

    特性: 1、支持任意深度的chm文件解析 2、解析后内容结构转换为tree数据呈现 3、点击树节点可以在html实时查看数据  4、不依赖任何浏览器端插件,兼容性较好

    2024年02月13日
    浏览(53)
  • Pdf文件格式解析:stream中的变换矩阵指令 1 0 0 -1 0 841.9 cm

    解释1 0 0 -1 0 841.9 cm 在PDF文件中的变换矩阵指令 1 0 0 -1 0 841.9 cm 中,前四个数值 1 0 0 -1 组成了一个2x2的线性变换部分,用于描述旋转和缩放操作,而不涉及平移。这里, 1 0 0 -1 的每一个数字都有特定的意义: 第一个数字 1 :这是矩阵的第一行第一列的元素。它决定了x坐标在

    2024年04月15日
    浏览(43)
  • 自定义鼠标指针——让你的指针瞬间变美

    首先,在开始今天的内容之前,我们先来看一下上次投票结果: 很明显,我们的“2号选手”顺利夺得了第一。 好,二话不说,开启今天的内容。 先来看一下我的鼠标指针:(额,我是个MC党(注:上一篇博客发迷你世界抢滩登陆只是素材需要,不要喷))  玩过MC的应该都

    2024年02月08日
    浏览(37)
  • 【音视频 | wav】wav音频文件格式详解——包含RIFF规范、完整的各个块解析、PCM转wav代码

    😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭 🤣本文内容🤣:🍭介绍wav音频格式🍭 😎金句分享😎:🍭子曰:父母在,不远游,游必有方。 ——《论语·里仁篇》。意思是,父母还健在时,就不要

    2024年02月06日
    浏览(60)
  • 鼠标指针经过时背景变色

    目录 一、如何使用鼠标指针经过时背景变色? 二、使用步骤 1.CSS(表格的样式) 2.表格(5行7列的一个表格) 2.Script部分(实现鼠标指针经过时背景变色效果) 总结 提示:以下是本篇文章正文内容,下面案例可供参考 在之前学习css的时候也学过hover的使用也可以进行该操作

    2024年02月12日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包