人工智能 720p ed2000(人工智能属于哪个专业大类)

Mark wiens

发布时间:2022-10-01

人工智能 720p ed2000(人工智能属于哪个专业大类)

 

是的,我指的是主流的,遍布全网的普通 gif,谷歌旗下的 Tenor 或 Facebook 旗下的 giphy 这样的网站到处都是这种 gif。Gif 是所有人都喜欢的,用来分享简短动画片断的文件格式。

大多数人眼中的 gif

正如大多数人所知道的那样,gif 是一种动画文件格式。你可能看过 gif 文件的信息,觉得这些文件可真够大的。也许你看了它们后会想:哇,这些图片的清晰度好低啊。但不管怎样,提到 gif 时,你对它的印象应该就是一种短小的动画文件格式。

然而,这种用例和编写 gif 的开发者所期望的用途大相径庭。在这篇文章中,我们将深入了解 gif 文件的结构,并在这一过程中讨论它的一些有趣特性。

请注意,这篇文章要探索的是如何理解 gif 格式这一主题,并考察它的一些更深奥的特性。如果你想深入学习如何解析 gif 文件,我推荐以下这些资源。

W3规范Matthew Flickinger:gif里有什么?我发现 ntfs.com 的这份指南也可以帮助入门

写文章的时候我实际上用这些资源做了一个勉强符合要求的 gif 解析器,名为awful-gif,可以解析一些 gif。我不建议大家使用它。

下面进入正题。

gif 的历史

gif 文件格式是由 Compuserve 在 1987 年创建的。在 1987 年的时候,gif 还是一个相当紧凑的格式!它使用了压缩方法,而且不是一般的压缩方法,而是 LZW 压缩技术。许多旧的文件格式(其中有些是 Compuserve 制作的)使用的则是 RLE(Run Length Encoding),在许多情况下效率没那么高。gif 的一个重要取胜因素就是其良好的压缩率和色域(全 256 色,太棒了!)。(注 1)

两年后,gif 文件格式加入了补充内容(gif89a),增加了许多我们今天众所周知和喜爱的特性。

通过 gif89a规范,我们可以快速总结出 gif89 与 gif87a 支持的所有特性的区别。

AppendixA.QuickReferenceTable.BlockNameRequiredLabelExt.Vers.ApplicationExtensionOpt.(*)0xFF(255)yes89aCommentExtensionOpt.(*)0xFE(254)yes89aGlobalColorTableOpt.(1)noneno87aGraphicControlExtensionOpt.(*)0xF9(249)yes89aHeaderReq.(1)nonenoN/AImageDescriptorOpt.(*)0x2C(044)no87a(89a)LocalColorTableOpt.(*)noneno87aLogicalScreenDescriptorReq.(1)noneno87a(89a)PlainTextExtensionOpt.(*)0x01(001)yes89aTrailerReq.(1)0x3B(059)no87aUnlabeledBlocksHeaderReq.(1)nonenoN/ALogicalScreenDescriptorReq.(1)noneno87a(89a)GlobalColorTableOpt.(1)noneno87aLocalColorTableOpt.(*)noneno87aGraphic-RenderingBlocksPlainTextExtensionOpt.(*)0x01(001)yes89aImageDescriptorOpt.(*)0x2C(044)no87a(89a)ControlBlocksGraphicControlExtensionOpt.(*)0xF9(249)yes89aSpecialPurposeBlocksTrailerReq.(1)0x3B(059)no87aCommentExtensionOpt.(*)0xFE(254)yes89aApplicationExtensionOpt.(*)0xFF(255)yes89alegend:(1)ifpresent,atmostoneoccurrence(*)zeroormoreoccurrences(+)oneormoreoccurrences

对于没有读过整份规范的人们来说,这里面的大部分内容可谓不知所云,所以让我们讨论一下 gif 是如何组合在一起的,顺便再谈谈它的一些奇怪之处。

在我们开始之前,先从规范中找些乐趣。

Appendix D. Conventions. Animation - The Graphics Interchange Formatisnotintendedasa platformforanimation, even though it can be doneina limited way.

附录

D.公约。

动画——这个图形交换格式不是要成为一个动画平台,尽管它在某种程度上可以做到这一点。

gif 的结构

下面我会用一个例子来具体分析。如果你想跟着做,下载它即可。(注 2)

如果你在家里跟着学,只需要一台安装有 hexdump 工具的机器即可。我要用的是 xxd,它预装在大多数 unix 系统(Linux、macOS)上,或者可以通过vim-common包安装。

gif 头

每个 gif 都以一个头开始,其中的 magic 位标志着它是什么类型的 gif,还有一点额外的信息,提供关于图像的基本细节。

xxdSunflower_as_gif_websafe_89a.gif|head-1and some arrows00000000:->474946383961<-dc000501f70000020102gif89a..........

用 xxd 可以轻松把 gif 头信息解码为 ascii(如果它有意义的话)。看看上面的内容写着,gif89a!这是一个经过认证的有效 gif!

每个字母都是一个字节,所以我们在这里要找的 magic 字节是:0x47、;0x49、0x46、0x38、0x39、0x61。

另外,最后三个字节可能是:0x38、0x37、0x61,如果只支持 gif87a 文件格式会是这样。我们主要研究 gif89,老版本的格式就一带而过了。

此外 gif 头里面就没有什么有趣的东西了,因为它只是静态文本,所以我们继续往前走。

先等一下问个问题:谁会接受 gif87a 呢?

在研究 gif 时,我想看看主要的 gif 托管供应商是否会接受和保留 gif87a 规范的格式。它们能正常使用吗,还是说只能报错?

这是我们之前看到的向日葵的 gif87a 版本。这个版本只用在这里。

我们来把图像上传到 4 家头部 gif 托管供应商:

tenorgiphyimgurgfycat

我们开始的时候 gif 头是这样:

xxdSunflower_as_gif_websafe_gif87a.gif|head-100000000:474946383761fa002901f50000ffcc33gif87a..)......3

以下是重新下载我刚上传的图片后的结果。

Tenor 重编码为 gif89a:

Downloadsxxdtenor.gif|head-100000000:474946383961a401f201f70000060406gif89a..........

giphy 重编码为 gif89a:

Downloadsxxdgiphy.gif|head-100000000:474946383961fa002901f52500000000gif89a..)..%....

其实这有点忽悠人,giphy接受动画形式的 gif,所以我们必须点击编辑按钮(显示帧编辑器),然后点击完成才行。gif87a 规范中允许存储多张图片,但它们不能有延迟(因此没有动画,见注 3)。

imgur 保留了原始文件!!!

DownloadsxxdaUxm3NN.gif|head-100000000:474946383761fa002901f50000ffcc33gif87a..)......3

至于 gfycat,它一直卡在最后的编码阶段整整 20 分钟。希望我没有在周末让他们的一位可怜的工程师看到什么警报。

以上简短分析表明,由世界上最大的两家科技公司所有的两家最大的托管供应商并不尊重我的旧 gif 文件,而是完全重写了它。事实上,对于 giphy 这家公司来说,它似乎只尊重一种 gif......

总之回到探索文件格式的话题上。

逻辑屏幕描述符

那么你的图像是如何显示成某个分辨率的呢?假设我们在 macOS 的 Preview 中使用get info特性,它是怎么知道这张图片是 220x261 的?

信不信由你,这是在文件格式中内置的!(注 4)

字节 0x6-0xA 就是这部分信息,另外还加了点内容。字节 0x6 和 0x8 指的是长度和宽度。

xxdSunflower_as_gif_websafe_89a.gif|head-1and some arrows00000000:474946383961->dc000501<-f70000020102gif89a..........

每个维度有两个字节来指定大小。同样一定要记住,gif 文件格式中的所有字节都被指定为小 endian(注 5)。

首先是宽度,是 0x00dc(从 dc00 重新排序)=> 220(十进制)。

然后是长度,是 0x0105(从 0501 重新排序)=> 261(十进制)。

慢着,这是否意味着我们的 gif 有一个分辨率限制?

这就对了!因为每个位置只有两个字节,所以宽度或长度都不能大于 65535。我们可以尝试在 gimp 中制作一个 1x65536 的新 gif 来验证这

其他文件格式在这方面也差不多。如果你想下载理论上最宽的 png,可以点这里。这个文件很小,但打开它的时候你的图像浏览器可能会崩溃。Firefox 浏览器很难打开它,并报告了一个错误,尽管它是符合规范的。

回到逻辑屏幕描述符上

不过逻辑屏幕描述符还没说完,接下来是一组打包的字段。用规范中的图表解释比较容易。

Fields> =GlobalColorTableFlag1BitColorResolution3BitsSortFlag1BitSizeofGlobalColorTable3Bits

这里有关于全局颜色表(Global Color Table)的信息,如果设置了全局颜色表位,它将出现在逻辑屏幕描述符之后。

颜色分辨率(Color Resolution)决定了全局颜色表中每种颜色有多少个字节。

排序标志(Sort Flag)会告诉解码器排在前面的颜色更重要,它会以有用的程度从高到低排序颜色。

而全局颜色表的大小是说,颜色表有多大。

在我们向日葵图片的 0xA 字节中,我们有 0xF7 的结果

xxdSunflower_as_gif_websafe_89a.gif|head-100000000:474946383961dc000501->f7<-0000020102gif89a..........

或者在二进制中就是:1111 0111

这意味着我们的 gif 基本满载,除了 GCT 没有排序。

┌──────────GCT not sorted ▼ by importance 1111 0111 ▲─── ─── GCTset───────────┘ ▲ ▲ │ │3bytesper │ └─────GCTis768bytescolor ─────────────┘ (maxsize) (maxresolution)

全局颜色表保存了每个字节部分所使用的颜色。它们是 0-255 的标准 RGB 值,你可以在任何现代 RGB 取色器里使用这些数值。

等一下,那个全局颜色表是可选的吗?

你可能已经注意到 0xA 字节的第一位说 GCT 可以是可选的。这的确很有趣。我们如何在没有指定它需要什么颜色的情况下渲染图像呢?

根据下面的规范:

颜色表——全局颜色表和局部颜色表都是可选的;如果存在全局颜色表,它将用于数据流中没有给出局部颜色表的所有图像;如果存在局部颜色表,它将覆盖全局颜色表。然而,如果两个颜色表都不存在,应用程序可以自由地使用一个任意的颜色表。

如果我们拿走一张图像的全局颜色表,现代渲染器会对我们的图像做什么呢?我敢肯定会有一些惊人的事情发生。

我们的图像指定的颜色表大小为 768 字节。它从 0xA 字节开始......假设我们像这样把 0xA 字节的最有意义的比特清零。

然后删除到第 789 字节(独占)。

xxdSunflower_as_gif_89a-no-gct.gif|head-100000000:474946383961dc000501007f8121f904gif89a.......!..

现在第一行是上面这样结束的,这仍然是一个完全有效的 gif,长成这样子:

简直了!在写这篇文章的时候,它就只显示一个完美的黑色方块。在我试过的每一个渲染器中都是这样的情况。Gimp、Chrome、Firefox、Preview、gifiddle,随便哪个都一样。

总之回到逻辑屏幕描述符上。

继续谈逻辑屏幕描述符

互联网小常识:高端路由器一般用作主干路由器,企业级路由器一般用作汇聚级路由器,低端路由器一般用于接入路由器。从内部结构分类,可以分为固定端口交换机与模块式交换机。

在描述全局颜色表的字节之后,有两个描述屏幕描述符的末端字节。

字节 B 是背景颜色,指的是全局颜色表的索引;字节 C 是像素长宽比,描述了像素的方正度。

xxdSunflower_as_gif_websafe_89a.gif|head-100000000:474946383961dc000501f70000020102gif89a..........^^|| Background color is color in index 0 of | GCT | Pixel aspect ratio is 0:0 or host pixel aspect ratio.

等一下,像素长宽比是什么?

像素并不总是正方形的!字节也不总是 8 位,但这一点就不多说了。

gif 和其他一些最流行的现代图像格式都支持非正方形像素。

我想知道最流行的 gif 渲染器在渲染非方形像素时兼容性如何。我们在 Firefox 和 Chrome 中做一个流行的测试,看看它们看起来如何:http://frs.badcoffee.info/PAR_AcidTest/

上面依次是:jpg、png 和 gif。而 Firefox、Chrome 和 Preview 都忽略了长宽比。

不幸的是,这一特性普遍不被支持,而且目前在 Firefox 中有一个 16 年的老 bug:https://bugzilla.mozilla.org/show_bug.cgi?id=333377

甚至 gifiddle 这个我能找到的兼容性最好的 gif 浏览器也不支持非方形像素:https://github.com/ata4/gifiddle/issues/1

如果你真的想显示非方形像素,可以用调整过的gimp来做。此外,grafx2 显然可以处理非常特定的奇怪像素分辨率。不过我还没有亲自测试过。

回到全局颜色表

全局颜色表(GCT)显然是 gif 最无聊的部分。这里真的没有什么值得谈论的东西。

我的 awful-gif 项目可以输出向日葵的 GCT 中的所有颜色(也许其他图像也行)。

GCT 的解析就在这里,你可以看到它真的没有什么特别的地方。

用下面的命令运行:

cargo run--quiet -- --gif-file ./experiments/Sunflower_as_gif_websafe.gif

可选的图形控制扩展

下面我们讲图形控制扩展(GCE),由扩展引入器 0x21 引入(extension introduced),然后是 0xF9(!)

可用的扩展有许多,但图形控制扩展可以说是最重要的扩展之一,至少在现代用例中是这样。GCE 允许各帧之间存在显示延迟,这样 gif 才能成为动画。GCE 还允许其他一些事项。

xxdSunflower_as_gif_websafe_89a.gif|head-50|tail-200000300:88aeb091a5b1a4b9be94887f81->21f904.............!..00000310:00000000<-0021fe5146696c6520736f75.....!.QFilesou

这个 gif 并不是动画,所以这里并没有发生很多事情。正如你所看到的,上面有很多零,但我们还是一个字节一个字节来讲。

第一个字节是块大小,在这个例子中是 0x04,但实际上根据规范它总是 0x04。

等一下,我们能不能把块大小去掉?

如果块大小总是一个静态的常数,那么它就不太重要了是吗?从技术上讲,它是规范的一部分,但实际上并没有什么作用。我们再在流行的图像浏览器中打开它看看。

在这些测试中我将使用一个更简单的 gif,这样更容易看到发生了什么情况:

在下面的测试中我对它做了修改,删除了 GCE。修改后的版本以 xxd 格式保存在下面。

00000000:47494638396120003400f0ff00ffffffgif89a.4.......00000010:00000021f90305000002002c00000000...!.......,....00000020:200034000002788c8fa9cb0b0fa394ed.4...x.........00000030:cc7babc11cead0755fc88d64a69d68a5.{.....u_..d..h.00000040:4e66eba5702c3675cddca5bde34ebfcbNf..p,6u.....N..00000050:0131ace1ea47040591289f4297142667.1...G...(.B..&g00000060:a70d3564bd1ab52e25b7f9058729de31..5d....%....).100000070:cd1cc9a2016a74dbfc1ec7c3f36f9d7b.....jt......o.{00000080:d7e6af7b6a7ff60713d832a8525855e6...{j.....2.RXU.00000090:9608b728d748f7681789f751b9500000...(.H.h...Q.P..000000a0:3b;

将其保存到一个名为 invalid.hex 的文本文件中,然后执行:xxd -r invalid.hex > invalid.gif

(更新的字节在:0x16,从 0x4->0x03)

第一个是 macOS Preview:

Preview 是符合标准的!

接下来我们试试 Firefox:

Firefox 知道这是一个静态值,并忽略了它的结果。这并不完全符合标准,但可能是最聪明的做法。

当块大小被移除后,Chrome 会有点抓狂。在这里,Chrome 肯定是最不符合标准的。

回到图形控制扩展

在我们读完块大小之后,是一个包装好的字段,描述如下。

Fields> =Reserved3BitsDisposalMethod3BitsUserInputFlag1BitTransparentColorFlag1Bit

在我们的图像中所有这些字段都被设置为 0,所以我只解释它们。

互联网小常识:服务器在进行文件传送时要求用户输入账号和密码,但是可以使用“匿名FTP服务”来使用户不用输入密码。

Reserved 是为 gif22a 出现时设置的,我们需要这三个位来做一些好事。

User Input 是为了接受用户输入,通过点击鼠标或按下键盘将 gif 图片推进到下一幅。

透明索引是用来设置我们是否应该允许透明。

等一下,gif 可以接受用户输入???

是的,你没看错。gif 可以接受用户的输入来推进到下一帧。这个可怜的家伙为了用 png 重现这一特性建立了一个网站。真可惜,他像我一样被困在这里了,就因为他没看过 gif 规范。

我们不妨讨论 gif 支持的另一个奇怪特性,即纯文本扩展。

纯文本扩展允许 gif 制作者在他们喜欢的任何地方嵌入单色文本,并直接在图像上进行一些基本的样式设计。

纯文本扩展和用户输入扩展一样,除了像 gifiddle 的这样为了好玩而制作的 gif 查看器外,可能从未被任何 gif 查看器实现。

BOB_89A.gif 可能是有史以来在互联网上发布的第一个 gif,是一个同时使用这两种方式的 gif 例子。

下面是 BOB_89A.gif 在现代浏览器中的渲染。

然而,如果你把它放到 gifiddle 中,会得到一个非常不同的结果,最后的信息是一个非常重要的事实。

不过我不会剧透这个惊喜。你可以下载这个 gif 放到 gifiddle 里,看看会发生什么。

gifiddle 链接:http://ata4.github.io/gifiddle/

任何现代浏览器或 gif 浏览器都不支持这两项特性。

如果你想阅读更多关于纯文本扩展的信息,可以看这里。

可选的注释扩展

接下来是注释扩展,实际上它可以出现在一个块可能开始的任何地方。然而它最常出现在 gif 的这一部分。

注释部分只允许包含 7 位的 ascii,并且是供人类阅读的。

由于注释部分只是 ascii,你可以直接发射字符串并在输出中找到注释。

stringsSunflower_as_gif_websafe_89a.gif|head-7|tail-1QFile source:https://commons.wikimedia.org/wiki/File:Sunflower_as_gif_websafe.gif

在这张图片中,它开始于图片的 0x310 字节。

xxdSunflower_as_gif_websafe_89a.gif|head-55|tail-600000310:000000000021fe5146696c6520736f75.....!.QFilesou00000320: 7263 653a 2068 7474 7073 3a2f 2f63 6f6d rce:https://com00000330:6d6f6e732e77696b696d656469612e6fmons.wikimedia.o00000340:72672f77696b692f46696c653a53756erg/wiki/File:Sun00000350:666c6f7765725f61735f6769665f7765flower_as_gif_we00000360:62736166652e676966002c00000000dcbsafe.gif.,.....

图像数据的剩余部分

之后就没有什么可谈的了。这张图像跳过了大多数其他的 gif 特性,如本地颜色表和动画,所以这张 gif 剩下的大部分只是数据和终止符。

老实说 lzw 压缩并不难学,但本文并不是要讲这个话题。如果你想学习它,Matthew Flickinger 在他的网站上有一篇好文章。

附加内容:真彩 gif

你知道 gif 可以是真彩色的吗?这和局部颜色表有关系。每个数据段都允许有自己的局部颜色表,因此如果你把一个 gif 分成足够多的片断,你就可以得到真彩色了!

大多数 gif 不会这样做,有几个原因。

首先,这样生成的图像是非常大的。每一个新的 256 色调色板将消耗额外的 768 字节。

第二,现在的渲染器不会正确渲染这样的图像。浏览器在默认情况下,如果没有指定,通常会在帧之间设置 0.1 的延迟。

然而,一个真正符合规范要求的 gif 渲染器会正确地显示真彩色 gif。因此,如果你有足够的空间、内存和多余的 CPU,为什么不做一个真彩 gif 呢?

如果你想了解更多关于真彩 gif 的信息,维基百科上有一整个章节。

总结

感谢大家有耐心看到这里。gif 规范中还有更多部分我没有讲到,如果你有兴趣了解更多关于 gif 的信息,我建议你查看规范和我在文章顶部添加的那些链接。

注释

https://en.wikipedia.org/wiki/gifhistory︎向日葵图片转自维基百科关于 gifs 的文章(见脚注 1)︎gif87a 在技术上是以比较有限的格式支持动画的。要了解更多信息,你可以试试 gifiddle 仓库上的 gif87a 动画例子:https://github.com/ata4/gifiddle︎更多信息请参见 gif 规范的第 18 节(逻辑屏幕描述符)。更多信息,请参见第 4 节。文档来自 gif 规范:https://www.w3.org/Graphics/gif/spec-gif89a.txt︎

互联网小常识:VLAN的特点:a、工作在数据链路层b每个VLAN都是一个独立的网段,独立的广播域c每个都有各自唯一的子网号,通信需要第三层的路由功能。

免责声明:本站所有信息均搜集自互联网,并不代表本站观点,本站不对其真实合法性负责。如有信息侵犯了您的权益,请告知,本站将立刻处理。联系QQ:1640731186