当前位置: 首页 > Web前端 > HTML

GIF格式分析表情符号的工作原理

时间:2023-03-29 11:43:39 HTML

前言《没有表情怎么聊天?作为打破人类交流困境的神器,没有什么场景是表情包表达不了的。想象一下,当你同时打开N个VSCode代码的时候,突然传来一声清脆的DING~,产品经理发来信息:昨天说的bug修复了吗?本着“能发图就不要打字”的原则,是时候使出收藏夹里的大杀器了↓简单的动画营造出进退自如的交流空间。这些动图就是我们平时用的GIF。业务背景然而,在风控场景中,黑灰易利用GIF图片的多帧特性,将非法图片注入其中,然后手动修改文件扩展名,伪装成普通图片,这无疑增加了风险防范的难度。和控制。.闪烁的非法主图让运营商防不胜防;画面最终定格在了看似没有问题的最后一帧,让操作者很难捕捉到有效的关键信息。GIF图片虽然具有“移动”的特性,但在Web上与图片一样对待,没有提供特殊处理API,因此无法控制GIF图片的播放、暂停、结束监听等事件。那么有没有什么办法可以把一闪而过并定格在最后一帧的GIF图片“移动”呢?接下来,让我们深入分析一下GIF图片。GIF格式介绍图形交换格式(GraphicsInterchangeFormat),简称GIF,是一种以8位颜色(即256色)再现真彩色图像的位图形文件格式。GIF文件分为许多存储块,用于存储多个图像或控制块,用于确定动画和交互式应用程序的图像行为。GIF有两个版本,GIF87a和GIF89a。GIF是一种位图。位图的一般原理是:一张图片是由许多像素组成的,每个像素被赋予一种颜色,这些像素组合起来就形成了一张图片。8位“位”是颜色深度。颜色深度由图像的位深度决定。简单的说就是最多支持多少种颜色(比如位深为1的像素有两个值:黑色和白色。位深越大,图像可以包含的颜色越多,越准确色彩表现,8位GIF图片最多包含256种颜色)GIF87a版本于1987年推出,一个文件存储一张图片,严格不支持透明像素;GIF87a使用LZW压缩算法,可以在保持图像质量的同时将图像尺寸减小20%到25%。GIF89a版本是1989年推出的一个非常有特色的版本,这个版本允许一个文件存储多张图片,启用动画功能,并允许某些像素点透明。该版本为GIF文件扩展了图形控制块、备注、说明、应用程序接口4块,并提供透明色和多帧动画支持。如果连续播放这些图像,就可以组成最简单的动画。因此,它常被用来存储“动态图片”,这些图片通常时间短、体积小、内容简单、成像比较清晰。我们现在谈论的第一个GIF版本是89a格式。GIF文件结构拆解要想知道图片是如何“动”的,首先要了解它是如何存储的。下面我们参考网上的一张图片,看看GIF格式的图像文件结构:图片来源:What'sInAGIFGIF格式文件以块为单位存储,整体分为三部分:文件头(Header)GIF数据流(GIFDataStream)在文件末尾(Trailer)其中,我们跳过了数据流中的文本扩展块、应用程序扩展块和评论扩展块。让画面“动起来”的秘诀就存在于图形控制扩展(GraphicControlExtension)当中。让我们举个栗子来了解一下。样品准备当打开样品图像时,可见图像将具有瞬间闪烁效果。十六进制转换Portal文件头识别一张图片是否是GIF不能只看图片扩展名格式或者图片是否会动。GIF文件的前6个字节是GIF的签名和版本号,可以通过控制台打印出来我们可以得到:根据ASCII码可以得到GIF89a对应的474946383961简单!继续往下看↓GIF数据流图形控件扩展我们通过观察不难发现,图片会有瞬间闪烁的效果。对比文章开头的表情包图片,为什么有的GIF图片可以一直循环播放,有的瞬间闪烁然后定格在第一帧第二帧呢?在89a版本中,GIF增加了一个图形控制扩展块,放在图像标识符(ImageDescriptor)之前,控制紧跟其后的第一张图像的显示。图形控制扩展块结构如下图所示:从上图可以看出,整个扩展块结构如下:descriptionlength扩展块标识1字节,固定值0x21扩展块标识1字节,固定值0xF9扩展块子块长度1字节保留位3位处理方法3位用户输入标志1位透明色标志1位延迟时间2字节透明色索引1字节扩展块尾部1字节,固定值0x00找到了!罪魁祸首是滞后时间!延迟时间标志着在继续处理数据流之前需要暂停这个延迟时间。这里可以理解为动画中每一帧的停留时间,单位是1/100秒。分析到这里,有种豁然开朗的感觉。回到代码,我们可以通过控制台看到从原图解析出来的数据:延迟时间:0000,十六进制转十进制:0我们通过手动设置延迟时间,可以让闪烁的图片“动起来”:手动修改延时时间:3200,十六进制转十进制:800核心代码如下:设p=0;//当前Buffer处理对应的下标while(notEndOfFile&&p