favicon.ico 里应该放哪几个尺寸?
16、32、48 三档 这三档分别对应浏览器标签页、Alt-Tab 切换器和桌面,从 1995 年起就是推荐组合。只有当图标还要在大图标视图里立得住时,才需要再加 256。
把 PNG、JPG、SVG、WebP 转成真正的多尺寸 ICO 图标:16/32/48 打包进一个文件,透明背景完整保留。内嵌 PNG 还是未压缩位图可选,两种体积当场对照。浏览器本地转换不上传,也能把 ICO 拆开逐尺寸导出 PNG。
把图片拖到这里,或点击选择
PNG、JPG、SVG、WebP、GIF、BMP · 单文件最大 10 MB
两种在 .ico 里都合法。PNG 自 Vista 起被 Windows 支持,所有现代浏览器也都认;而抽样 20 个站点里能解析出的 14 个真 ICO 中,有 13 个用的是未压缩位图,因为 ImageMagick 默认会转成它。
<link rel="icon" href="/favicon.ico" sizes="16x16 32x32 48x48"> <link rel="icon" type="image/svg+xml" href="/icon.svg"> <link rel="apple-touch-icon" href="/apple-touch-icon.png">
把 .ico 文件拖到这里,或点击选择
文件里的每一档都会单独列出来
| 偏移 | 字节数 | 字段 | 值 |
|---|---|---|---|
| 0 | 2 | idReserved | 0 |
| 2 | 2 | idType | 1 |
| 4 | 2 | idCount | 3 |
| 6 | 1 | bWidth[0] | 16 → 16 |
| 7 | 1 | bHeight[0] | 16 → 16 |
| 8 | 1 | bColorCount[0] | 0 |
| 9 | 1 | bReserved[0] | 0 |
| 10 | 2 | wPlanes[0] | 1 |
| 12 | 2 | wBitCount[0] | 32 |
| 14 | 4 | dwBytesInRes[0] | 248 |
| 18 | 4 | dwImageOffset[0] | 54 |
| 22 | 1 | bWidth[1] | 32 → 32 |
| 23 | 1 | bHeight[1] | 32 → 32 |
| 24 | 1 | bColorCount[1] | 0 |
| 25 | 1 | bReserved[1] | 0 |
| 26 | 2 | wPlanes[1] | 1 |
| 28 | 2 | wBitCount[1] | 32 |
| 30 | 4 | dwBytesInRes[1] | 720 |
| 34 | 4 | dwImageOffset[1] | 302 |
| 38 | 1 | bWidth[2] | 48 → 48 |
| 39 | 1 | bHeight[2] | 48 → 48 |
| 40 | 1 | bColorCount[2] | 0 |
| 41 | 1 | bReserved[2] | 0 |
| 42 | 2 | wPlanes[2] | 1 |
| 44 | 2 | wBitCount[2] | 32 |
| 46 | 4 | dwBytesInRes[2] | 1464 |
| 50 | 4 | dwImageOffset[2] | 1022 |
由开发 Go Tools 转换类工具的工程师撰写与复核。页面里关于容器结构、字节数和失败形态的说法,来自一份书面的领域评审,而不是转述别人对这个格式的概括。
16、32、48 三档 这三档分别对应浏览器标签页、Alt-Tab 切换器和桌面,从 1995 年起就是推荐组合。只有当图标还要在大图标视图里立得住时,才需要再加 256。
能,它就是干这个的 这个格式本身就是容器:六字节文件头,每张图一个十六字节目录项,然后才是图像。每一档都是分别画好的图,好图标在 16 像素下依然清晰靠的就是这一点。
做对了就不会 容器内部两种存法都带完整的 8 位 alpha 通道。只有当工具把 alpha 字节留空、或者丢掉老软件改读的那张 1 位掩码时,透明才会丢。
未压缩 264 KB,PNG 只要几 KB 未压缩的 256 档正好是 270,376 字节——40 字节头、262,144 字节像素、8,192 字节掩码——与画的是什么无关。同一档存成 PNG 通常只要几 KB。
与其说 .ico 是一种图片格式,不如说它是一个装图片的小档案包。开头六个字节说明里面有几张图,接着每张图对应一个十六字节的目录项,记着它的宽、高、字节数和在文件里的位置,再往后才是图像数据本身。每张图有两种存法:作为一个完整的 PNG 文件整个嵌进去,或者存成未压缩的 Windows 位图,底下再挂一张 1 位的透明掩码。
正因为这个设计,同一个网站图标才能在浏览器标签页上以 16 像素清晰显示、在文件管理器里以 48 像素同样清晰——它们是分别画好的几张图,不是一张图被缩来缩去。也正因为这个设计,格式里藏了几个意外:边长只用一个字节存,所以 256 要写成 0,而 512 根本没法写;目录里为每一档记了一个尺寸,图像数据自己也记着一个尺寸,两者可能对不上——而不同软件信的偏偏不是同一个。
$ file favicon.ico
favicon.ico: MS Windows icon resource - 3 icons, 16x16, 32 bits/pixel, 32x32, 32 bits/pixel
$ python3 -c "from PIL import Image; print(sorted(Image.open('favicon.ico').ico.sizes()))"
[(16, 16), (32, 32), (48, 48)] 默认 16、32、48,最大到 256。每一档都是从原图单独画出来的,不是从上一档缩下来的,所以小尺寸不会继承大尺寸的模糊。
容器内部这两种合法存法取舍差别很大,而大多数转换器从不说明自己写的是哪一种。这里做成了开关,并把两种结果的文件大小都显示出来,选择基于数字而不是感觉。
alpha 通道完整写入,老软件改读的那张 1 位掩码也由 alpha 推导出来,而不是留空。掩码留空正是「透明图标在某些地方变成黑方块」的成因。
反向标签页会列出 ICO 里每一张图的真实尺寸、存储格式、位深和透明度来源——包括几个知名网站图标至今仍在用的调色板位图。浏览器永远只会给你看其中一张。
目录声明的尺寸与图像数据对不上时,这里会标出来。Firefox 会扔掉的内嵌 PNG 也会标出来——它的 ICO 解码器只收 8 位 RGB 或 RGBA,调色板或灰度的那一档在 Firefox 里直接消失,而别的浏览器全都正常显示。这两件事都是「图标在一个程序里正常、在另一个程序里空白」的常见原因,而别的转换器一件都不会告诉你。
读取、缩放、打包全部在这个页面里完成。文件不会到达任何服务器,所以事后没有什么需要删除,也不用排队。
magick in.png -define icon:auto-resize=48,32,16 favicon.ico 最常见的答案,也是那么多网站图标是未压缩形态的原因。除 256 档外每一层都会先转成位图再打包,所以三档出来是 15 KB 左右而不是几百字节。尺寸按从大到小写入。
img.save('favicon.ico', sizes=[(16,16),(32,32),(48,48)]) 内嵌 PNG,同样三档只占大约十分之一的空间。Pillow 读 ICO 也很好用:Image.open(f).ico.sizes() 会列出里面有哪几档,查别人的文件时很方便。
npx png-to-ico icon.png > favicon.ico 单一用途的命令行工具,接收一个或多个 PNG 并以 PNG 载荷打包。放进构建脚本很方便;它不替你缩放,每一档都要你自己准备好文件。
sharp(input).resize(32).png() 生成各档 PNG 非常好用,但它不写 ICO 容器,所以通常要配合上面某个打包工具。构建流程已经统一用 sharp 的项目常在这里卡住。
github.com/Kodeworks/golang-image-ico 从 image.Image 写出单张图的 ICO。做一个单尺寸网站图标够用;要把多档装进一个容器就得自己写目录,大约三十行。
.rc 资源脚本 + rc.exe 应用程序图标的常规做法。编译器把 .ico 嵌进可执行文件的资源段,里面那个容器的格式与网页用的网站图标完全一样。
.ico 把图像的每个图层导出成一个图标尺寸,并允许逐层选择位深,包括压缩过的 PNG。少数几个把这个选择摆出来而不是替你默默决定的图形工具之一。
sips -s format ico in.png --out favicon.ico macOS 其实是带 ICO 写入器的:sips --formats 里 com.microsoft.ico 标着可写,上面这条命令在本机确实产出了合法文件。它做不到的是打包多档——输出只有单独一张 48×48。搜索结果通常推荐的 iconutil 产出的则是 .icns,苹果自家的容器,Windows 和浏览器都不认。
$ xxd -l 38 favicon.ico
00000000: 0000 0100 0300 1010 0000 0100 2000 e903 ............ ... 00000010: 0000 3600 0000 2020 0000 0100 2000 6c05 ..6... .... .l. 00000020: 0000 1f04 0000 ......
0000 是保留字段,0100 表示类型 1(图标,不是光标),0300 说明里面有三张图。接着是第一个 16 字节目录项:10 10 是 16×16,00 调色板色数,00 保留,0100 一个平面,2000 每像素 32 位,e903 0000 是 1,001 字节的载荷,位于偏移 3600 0000 = 54——正好是 6 + 3 × 16,也就是目录的末尾。除了单字节的尺寸,所有多字节字段都是小端。
bWidth = 0x00 bHeight = 0x00
256 × 256
目录里每条边只有一个字节,能装下的最大数字是 255,于是 0 被定义为表示 256。这也是本页不提供 512 的原因:根本没有哪个字节能表示 512。不少在线转换器照样提供这个选项,写出来的目录项描述不了自己后面那张图。
16 + 32 + 48 px, PNG payloads 16 + 32 + 48 px, uncompressed BMP payloads
389 bytes 15,086 bytes
未压缩载荷的体积是 40 + 宽 × 高 × 4 再加一张 1 位掩码,只跟尺寸有关,跟画的是什么完全无关。所以三个内容毫不相干的网站,图标文件大小可以一个字节不差。
$ magick logo.png -define icon:auto-resize=48,32,16 favicon.ico $ file favicon.ico
favicon.ico: MS Windows icon resource - 3 icons, 48x48, 32 bits/pixel, 32x32, 32 bits/pixel
ImageMagick 除 256 档以外,会把每一层都先转成未压缩位图再打包,所以它的产物是 15 KB 左右而不是几百字节。Pillow 的做法相反,内嵌 PNG:Image.open('logo.png').save('favicon.ico', sizes=[(16,16),(32,32),(48,48)])。
$ magick favicon.ico favicon-%d.png
favicon-0.png 48×48 favicon-1.png 32×32 favicon-2.png 16×16
浏览器替不了你做这件事。把一个多尺寸 ICO 交给 <img>,拿回来的永远只有一张图——最大的那张,不管里面的尺寸按什么顺序排。想知道文件里到底有哪几档,只能自己解析容器,这正是「ICO → PNG」标签页在做的事。
PNG、JPG、SVG、WebP、GIF、BMP 都收,单文件上限 10 MB。文件不会离开浏览器:用 File API 读进来,每个像素都画在本地 canvas 上。
默认勾好 16、32、48。图标要扛住大图标视图或高分屏时再加 64、128、256。如果源图比你勾的最大尺寸还小,页面会明说,而不是悄悄放大。
默认内嵌 PNG,因为它小一个数量级,而且所有现代浏览器和 Vista 之后的 Windows 都认。想要大多数线上图标的真实形态就切到未压缩位图。两种体积并排显示。
保存 .ico,需要 HTML 就点「复制 link 标签」。根目录的 /favicon.ico 仍然是有效的兜底路径,但浏览器被规定优先走的是显式的 link 元素。
256 像素图对应的目录字节必须是 0。写成 255 看着像个无害的差一错误,产物却会被某些浏览器悄悄拒绝绘制。
bWidth = 0xFF bHeight = 0xFF ; 写成「255」,本意是 256
bWidth = 0x00 bHeight = 0x00 ; 0 被定义为表示 256
当目录项写着 16×16、后面的载荷实际是 32×32 时,解码器会分成两派:一派信目录,结果什么都画不出来;另一派信载荷,正常渲染。于是同一个文件在一台机器上好用,在另一台上不见了。
目录项:16×16 载荷 IHDR:32×32
目录项:32×32 载荷 IHDR:32×32
未压缩层里的高度要把彩色数据和掩码一起算上。写成原始高度,会得到一个在某些解码器里显示为空白、在另一些里只显示下半截的文件,两边都不报错。
biHeight = 32 ; 用于一张 32 像素的图
biHeight = 64 ; 2 × 32,彩色数据加掩码
有些工具只填了掩码,把每个 alpha 字节都留成 0。一种解码器会把它读成整张全透明,图标就此消失;另一种会回退到掩码,显示正常。两者都写、且写得一致,就绕开了这场争论。
alpha 字节:全 0x00 掩码:全 0x00
alpha 字节:真实值 掩码:alpha < 128 处置位
SVG 被栅格化时,指向外部的引用会被拦掉,而且没有任何提示——不触发错误,canvas 也照样可读。碎图占位符就这样被烤进了图标。转换前把图形内联进去。
<image href="https://cdn.example.com/logo.png"/>
<image href="data:image/png;base64,iVBORw0KGgo…"/>
00 00 保留、01 00 表示图标(02 00 表示光标文件),再加两字节的数量。每个目录项依次是宽、高、调色板色数和一个保留字节,各占一字节;随后是两字节的平面数和位深,最后两个四字节字段给出载荷的长度和偏移。所有多字节字段都是小端。ceil(宽 ÷ 32) × 4 字节。于是 16 档是 1,128 字节,48 档是 9,640,256 档是 270,376——与画的是什么无关。这个固定开销解释了为什么三个毫不相干的网站能有字节数完全相同的图标文件,也是本页只在内嵌 PNG 时才提供 256 档的原因。image/vnd.microsoft.icon 于 2003 年 9 月在 IANA 登记,它引用的参考文献是 1995 年微软的一篇《Icons in Win32》。被广泛当成 ICO 规范引用的 RFC 2361,真实标题其实是《WAVE and AVI Codec Registries》,通篇没有一个字提到图像。magick logo.png -define icon:auto-resize=48,32,16 favicon.ico。 转换工具
在线免费进制转换工具,支持二进制、八进制、十进制、十六进制及 2-36 任意进制互转。无需注册,数据不离开浏览器,即时获取结果。
转换工具
在线原码/反码/补码计算器,一次算出原码、反码、补码与移码四种表示,支持 4/8/16/32/64 位。也可反过来粘贴 11111011 或 0xFB,看它按无符号、原码、反码、补码、移码分别读作多少。-128 在 8 位下没有原码和反码,本工具会明确标出并解释为什么。全程浏览器本地计算。
转换工具
在线 chmod 计算器:Linux 文件权限在八进制(755、644)与 rwx 符号之间双向转换,实时生成可复制的 chmod 命令,并自动提示 777 等高危权限。免费使用,全部在浏览器本地完成,数据不上传。
转换工具
在浏览器中将 HEX 转 RGB、HSL、OKLCH、OKLAB 与 CMYK,一键复制任意格式。免费、免注册,您的颜色永远不会离开本页。
转换工具
在浏览器中把 HEX 颜色转成 CMYK。基于 sRGB 的朴素近似,适合印前预览。免费、免注册,您的颜色始终保留在本地。
转换工具
在浏览器中把任意 HEX 颜色转成 HSL —— 3 位、6 位以及带 alpha 的 8 位全部支持。免费、即时、免注册,您的颜色永远不会离开本页。