有史以来最小的GIF/png/jpg/jpeg

昨天我对图像进行了 base64 编码,这样我就可以将它发送到 CouchDB 以测试我正在为客户编写的一些代码。 它让我想起了我之前在远程服务器上设置 cookie 时所做的事情。

基本上,一个小的 PHP 脚本被放在远程服务器上,它接受几个 GET 参数并根据它们的值设置一些 cookie。 然后脚本输出一个 1x1 的透明 GIF。 本地服务器上的 PHP 脚本生成了一个 IMG 标签,该标签链接到该图像并根据本地服务器上的 COOKIES 设置参数。

这个过程也必须反向进行,所以我不得不将脚本发送给另一边的开发人员。 我想让它尽可能简单,所以我将实际图像内容作为 base64 编码字符串放在 PHP 文件中。 我使用 GIMP 生成了我可以管理的最小的透明 GIF,因此文件中不会有 太大 的令人讨厌的字符串。 我想出了以下内容:

<?php
setcookie('foo', $_GET['foo']);
header('Content-Type: image/gif');
echo base64_decode('R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==');
?>

记住这一点让我想知道,你可以制作多小的 GIF? GIMP 生成的文件只有 43 个字节,但似乎您应该能够制作一个代表单个像素的文件,比它小一点。

因此,带着同样的决心和疯狂,我开始寻找答案。

尽管用处有点可疑,但我还是设法生成了一个长度仅为 26 字节的完全有效的 GIF,它有可能在各种不同的软件中以完全不同的方式显示。

继续阅读以了解我是如何找到这一点的。

起点:GIF89a 规范

正如我所说,由 GIMP 生成的文件有 43 个字节长。 你可以在这里找到它: tinytrans.gif

为了了解是什么占用了所有这些字节,我通读了 GIF89a 规范 。 上面的文件 tinytrans.gif 由以下部分组成:

  • Header , 6 bytes: 由字节“GIF”和版本号组成,通常为“89a”。
  • 逻辑屏幕描述符 ,7 个字节:无需过多赘述,文件的这一部分指示以下内容:
    • 文件大小为 1x1 像素
    • 有一个全局颜色表
    • 全局色表中有2种颜色,应该用第二种作为背景色
  • Global Color Table , 6 bytes:每种颜色由 3 个字节组成,一个字节分别代表红色、绿色和蓝色。 在我们的文件中,第一种颜色是白色,第二种颜色是黑色。
  • Graphic Control Extension , 8 bytes: 用于指示颜色表中的第二种颜色应该被视为透明(也可以用于动画参数,但不在本文件中)
  • 图像描述符 ,10 字节:一个 GIF 文件实际上可以在其中包含多个“图像”,这使您不必为与背景颜色具有相同颜色的图像部分指定图像数据。 每个图像块在整个图像尺寸内都有一个位置和尺寸。 在上面的文件中,位置是 0,0,大小是 1x1。
  • 图像数据 ,5 字节:一个 LZW 编码 的图像数据块。 它需要 5 个字节来表示图像中的单个像素。 压缩算法并不是为了很好地压缩单个字节而设计的。
  • GIF Trailer , 1 字节:十六进制值为 3B 的单个字节(ASCII 中的“;”)表示 GIF 的结尾。

制作较小的 GIF

根据透明 GIF 所需的结构,事实证明 43 字节非常接近您所能得到的最小值。

但是 ,我想出了一个办法让它变小一点。 标准中提到全局颜色表是可选的。 当然,当你制作一个根本没有颜色表的 GIF 时会发生什么是不确定的(每个图像块也有可选的局部颜色表)。

扫描二维码关注公众号,回复: 16104722 查看本文章

然而,当您将颜色表索引定义为透明时,GIF 解码器似乎并不关心实际上没有颜色表。

所以我更改了逻辑屏幕描述符以指示没有全局颜色表并删除了该表本身,总共节省了六个字节,使文件大小减少到仅 37 个字节。

这是它的全部荣耀: handtinytrans.gif

有趣的是,Wordpress 给了我一个可爱的 GD 错误消息列表,抱怨这不是一个有效的 GIF 文件,尽管 Firefox 和 GIMP 都打开并显示(当它是透明的时候它“显示”了吗?)文件正好。

所以你去吧,尽可能小的 透明 GIF(如果你能把它做得更小,请告诉我)。

仍然有空间。 最小的GIF 但是,当然,有史以来

更小,不再透明

为了让它更小,我查看了图像中最大的剩余“可选”块,即图形控件扩展。 如果您不需要透明度,则不再需要此块,您可以拿走另外 8 个字节。

可悲的是,我想要一个白色的图像,如果不重新添加全局颜色表我就无法让它变成白色,所以我只设法从文件中删除了 2 个字节。

尽管如此,35 个字节确实更小: handtinywhite.gif

最小的 GIF

如果我取消让图像为白色(或我选择的任何颜色)的限制,我可以将它变得更小,尽管不可否认这变得没那么有用了。

我删除了全局图像表和图形控件扩展,然后不管像素原来是什么颜色,它都是黑色的。 从那里,我更进一步,因为标准从来没有说你必须实际设置图像中的任何像素,我删除了 LZW 编码的图像数据。 我留下了所需的 lzw 代码大小标头和块终止符,因为没有这些 Firefox 和 GIMP 都抱怨它不是有效的 GIF,然后我得到了它。

有史以来最小的 GIF,26 字节: handtinyblack.gif

尽管这被称为“handtinyblack.gif”,但黑色只是 GIMP 在没有全局颜色表时选择显示的颜色。 规范中指出“如果根本没有可用的颜色表,解码器可以自由使用系统颜色表或它自己的表。”

这意味着任何 GIF 解码器都可以自由选择它想要的图像颜色。 在不同的时间在 Firefox 中打开此图像,它显示为蓝色、绿色和棕色的阴影,如果设置为背景图像,则显示为透明。

猜你喜欢

转载自blog.csdn.net/LingLing1301/article/details/128889996