透明单像素图像的最小文件大小

67

我正在寻找最小的(文件大小方面)透明的1像素图片。

目前我有一个大小为49字节的gif,似乎是最流行的。

但我记得许多年前有一个少于40字节的图片。可能是32字节。

有人能做得更好吗?图形格式无所谓,只要现代Web浏览器可以显示它并支持透明度即可。

更新: 好的,我已经找到了一个42字节的透明单像素gif: http://bignosebird.com/docs/h3.shtml

更新2: 看来少于43字节的可能在某些客户端中不稳定。不能这样。


9
我认为你手头有点太多时间了。这对实际上并没有任何影响... - ChristopheD
7
你实际拥有的内容远远超过49KB,因为HTTP头部比图片还要大 :) - Lukáš Lalinský
4
这个请求会导致比图像大小多得多的数据量,与请求大小相比,图像大小并不相关。 - Sander Rijken
3
必须考虑到最小数据包大小(以及最小的磁盘扇区)。 - lexu
2
@Dested,如果您在页面上有成千上万个相同的图像,则它们将被作为单个请求获取,并且很可能会被缓存以供后续页面使用。 - Sander Rijken
显示剩余6条评论
11个回答

98
首先,除非你正在处理复古风格的网站,否则在2020年及以后,实际上没有使用间隔GIF的有效理由,因此本文大多数内容只是为了好奇心。无论如何,让我们开始吧: 最小的有效透明GIF文件大小为35字节。
data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAIBAAA=

47 49 46 38 39 61 01 00 01 00 00 00 00 21 f9 04 01 00 00 00 00 2c
00 00 00 00 01 00 01 00 00 02 01 00 00

这将在每个浏览器中运行,无论是新的还是旧的,以及基本上任何图像编辑器/查看器。但是,它可能无法与弱GIF解析器配合使用,例如PHP图像库中的解析器。

为了获得完全覆盖,最小值增加到41字节:

data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAAAAAAALAAAAAABAAEAAAIBAAA=

47 49 46 38 39 61 01 00 01 00 80 00 00 FF FF FF FF FF FF 21 F9 04
00 00 00 00 00 2C 00 00 00 00 01 00 01 00 00 02 01 00 00

这里是解释。

最小可能的GIF取决于GIF规范的不同实现,这甚至会随着时间的推移而改变。网络浏览器通常对GIF渲染宽容和不一致,允许部分损坏的GIF显示。在回答的历史中,我曾制作过一个14字节的GIF,只有在Chrome中才是透明的,但现在已经不起作用了。有一个23字节的版本可以在Chrome和Firefox中使用,但最终在Firefox中不再透明。我选择了一个32字节的版本,认为它可以在任何地方使用,但后来发现它在Safari 14中无法使用。即使是一个修复了Safari 14的33字节版本,在Safari 15中也停止工作了!因此,显然最好遵循标准,不要依赖可能永远不起作用的hacky解决方案。虽然我还应该提到,自1996年以来,间隔GIF已经不再相关,您真的不应该使用它们。请改用CSS。我写这篇答案只是为了更多地了解GIF。

如果我们遵循官方GIF规范,我们得出的数字是43字节,由以下部分组成:

  1. 文件签名,6个字节
  2. 逻辑屏幕描述符,7个字节
  3. 全局颜色表,6个字节
  4. 图形控制扩展,8个字节
  5. 图像描述符,10个字节
  6. 压缩的LZW图像数据,5个字节
  7. 尾随符号0x3B),1个字节

这些中有些技术上是可选的。例如,尾随符号可以被安全地省略,并且不会影响图像的渲染。LZW数据可以通过将子块计数更改为1而不是2来减少到4个字节。这样就得到了上面的41个字节的GIF。然后我们可以通过关闭位标志来安全地禁用全局颜色表,在每个浏览器中都可以安全地使用,但可能会使无能的GIF解析器困惑。这样就得到了上面的35个字节。


1
很遗憾,在IE8中,32字节的GIF是黑色的 :( - tomasz86
很棒的回答!只是提一下第一个例子实际上是24字节,而不是23。 - ngryman
1
最新版本的Safari似乎对32字节的GIF文件损坏了。 - Ng Sek Long
1
@NgSekLong,我解决了这个谜团,只有在Safari中需要额外的字节等于0。 - bryc
@tomasz86 我修复了IE8,还有Safari 15变得更加严格了! - bryc
显示剩余3条评论

30

这是我在C#中使用的字节数组(避免了文件访问)

static readonly byte[] TrackingGif = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x1, 0x0, 0x1, 0x0, 0x80, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x2, 0x2, 0x44, 0x1, 0x0, 0x3b };
在ASP.NET MVC中,可以像这样返回此内容。
return File(TrackingGif, "image/gif");

1
是的,那就是想法。你有多少字节?抱歉,我现在太懒了,不想数 :) - zaf
1
35个字节,所以我猜这不是透明的。 - Nux
1
@Nux 不是透明的,它是白色(FFFFFF)。对于我的用途来说非常完美。 - WildJoe

20

看看这个 blank.gif 文件(43字节)。小于49 :D


11
似乎Blank.gif不是透明的。你可以使用以下内容(记得在“/”后面去掉空格):data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw== - Nux
1
数据字符串在像Polipo这样的缓存代理中不起作用,因此如果您处于这种情况下,可以在此处获取一个43字节的透明gif:http://probablyprogramming.com/2009/03/15/the-tiniest-gif-ever - thdoan

19

为了进一步解释Jacob的字节数组答案,我生成了一个c#字节数组,用于一个我在Photoshop中制作的透明1x1像素的gif图像。

static readonly byte[] TrackingGif = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x81, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e, 0x30, 0x03, 0x01, 0x01, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x08, 0x04, 0x00, 0x01, 0x04, 0x04, 0x00, 0x3b};

16

http://polpo.org/blank.gif是一个由gifsicle制作的37字节透明GIF。

以CSS就绪的base64格式:

data:image/gif;base64,R0lGODlhAQABAHAAACH5BAUAAAAALAAAAAABAAEAAAICRAEAOw==

7
  • See: http://www.google-analytics.com/__utm.gif, 35B

  • Alternative in Perl (45B):

    ## tinygif
    ## World's Smallest Gif
    ## 35 bytes, 43 if transparent
    ## Credit: http://www.perlmonks.org/?node_id=7974
    
    use strict;
    my($RED,$GREEN,$BLUE,$GHOST,$CGI);
    
    ## Adjust the colors here, from 0-255
    $RED   = 255;
    $GREEN = 0;
    $BLUE  = 0;
    
    ## Set $GHOST to 1 for a transparent gif, 0 for normal
    $GHOST = 1;
    
    ## Set $CGI to 1 if writing to a web browser, 0 if not
    $CGI = 0;
    
    $CGI && printf "Content-Length: %d\nContent-Type: image/gif\n\n", 
        $GHOST?43:35;
    printf "GIF89a\1\0\1\0%c\0\0%c%c%c\0\0\0%s,\0\0\0\0\1\0\1\0\0%c%c%c\1\
        +0;",
        144,$RED,$GREEN,$BLUE,$GHOST?pack("c8",33,249,4,5,16,0,0,0):"",2,2,4
    +0;
    

运行它...

$ perl tinygif > tiny.gif
$ ll tiny.gif
-rw-r--r--  1 stackoverflow  staff    45B Apr  3 10:21 tiny.gif

1
复制和粘贴对我没用(标识:损坏的图像)。可能是你的格式问题...?此外,代码注释说35/43字节,但你的输出显示为45字节。 - zaf
1
谷歌的 _utm.gif 似乎不够透明。 - briznad

4

透明点,43字节:

echo "\x47\x49\x46\x38\x39\x61\x1\x0\x1\x0\x80\x0\x0\xff\xff\xff\xff\xff";
echo "\xff\x21\xf9\x04\x1\x0a\x0\x1\x0\x2c\x0\x0\x0\x0\x1\x0\x1\x0";
echo "\x0\x2\x2\x4c\x1\x0\x3b";

橙色点,35字节:
echo "\x47\x49\x46\x38\x37\x61\x1\x0\x1\x0\x80\x0\x0\xfc\x6a\x6c\x0";
echo "\x0\x0\x2c\x0\x0\x0\x0\x1\x0\x1\x0\x0\x2\x2\x44\x1\x0\x3b";

没有颜色表(可能被涂成黑色),26字节:

echo "\x47\x49\x46\x38\x39\x61\x1\x0\x1\x0\x0\xFF";
echo "\x0\x2C\x0\x0\x0\x0\x1\x0\x1\x0\x0\x2\x0\x3B";

我早些时候发现了前两个(在timthumb漏洞的时代),我不记得来源了。最新的一个我在这里找到。

P.S.: 仅用于追踪目的,不要用作间隔符。


我猜这些都是GIF格式的图片? - lnafziger
是的,当然。请注意 GIF 文件的签名(47 49 46 = GIF)。 - s3v3n
2
这对那些了解GIF签名的人来说很棒。然而,许多人在这里寻找东西时并没有图像文件格式的背景知识,因此特别指出这一点是很好的。 :-) - lnafziger
1
那么以后参考的话,我会提交这个链接:http://en.wikipedia.org/wiki/Graphics_Interchange_Format#Example_GIF_file 一般来说,GIF格式是很好文档化的。 - s3v3n

1

我认为这是最令人难忘的 1x1(38字节):

data:image/gif,GIF89a%01%00%01%00///;

根据GIF头文件规范:
GIF Header

Offset   Length   Contents
  0      3 bytes  "GIF"
  3      3 bytes  "87a" or "89a"
  6      2 bytes  <Logical Screen Width>
  8      2 bytes  <Logical Screen Height>

首先,%01%00 表示宽度为 0x0001

请注意,1px 等于 %01%00,而不是 %00%01,否则会变成 0x0100

其次是高度,与上面相同

接下来的三个字节可以输入任何内容,浏览器可以解析它们

例如:///!!!,,,;;; 或者 +++

最后一个字节必须是:;, 或者 !

顺便说一下,如果在尺寸后面的三个字节中使用 /// 或者 \\\

页面标题将显示最后一个字符,否则将显示 gif,...

在 Chrome 和 Firefox 上测试通过,IE 不支持


仅仅是无效的。在我测试的任何浏览器中都无法正确渲染。 - bryc

0

2
不要忘记减去头文件中的几个字节,因为文件名稍微短一点 :-) - Sander Rijken

0

你不应该使用“空白gif”。它们在90年代被使用过,现在已经非常过时了,而且它们没有任何作用,会导致多种无障碍性和兼容性问题。

使用CSS。


5
我想这个仍然被用来追踪图片(例如追踪HTML邮件有多少人“打开”了)。虽然用法非常值得怀疑... - ChristopheD
3
@ChristopheD - 而且在所有明智的电子邮件客户端中默认被屏蔽(已经多年了),因此即使是那种可疑的用途也基本上没有意义。 - Daniel Earwicker
1
它对于轻松破解同域策略非常有用,可用于事件跟踪或日志记录等目的。比基于iframe的方法更加优雅。 - Viliam
1
@Villiam:对此,一个没有内容的CSS会更好。 - Andreas Bonini
不确定为什么它是-1,我+1这个答案来恢复平衡...安德烈亚斯是正确的;间隔图像已经过时了。上面的评论可能是正确的,但超出了答案的范围,它们谈论的是跟踪器,而不是间隔符。而且,跟踪器也不需要是透明的。 - PhiLho
2
这应该是一条注释而不是回复。 - Zac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接