做网站的时候总会遇到同一个卡点:手上只有一张 PNG 或 JPG,而 favicon.ico 必须是 ICO 格式。Windows 桌面快捷方式、部分老系统的任务栏、还有一些抓取工具,认的仍然是那个 .ico 后缀。找在线转换站,一半要先看广告,一半会把图片来源上传到别人的服务器——图标不算机密,但「给客户做的品牌标识先传到了陌生站点」这件事,总归不太体面。

ICO Transform Online 就是这种场景下的最小解:一个 PHP 单页工具,把 JPG / PNG / GIF 转成 ICO,保留透明背景,可以直接丢到自己服务器上跑。项目在 GitHub 上叫 Nyaasu66/ico-transform-online,主语言 PHP,仓库不到 500KB,2019 年 8 月建仓,最近一次提交在 2026 年 4 月,约 24 星、2 个 fork,没有挂许可证文件。作者有个演示站在 ico.nyaasu.top,界面长这样——

ICO 图标在线转换工具界面:上传源图、选择目标尺寸、生成 ICO 图标

一、一屏之内,只有三个动作

整个工具就一屏:左边上传源图,右边勾尺寸,下面一个「生成 ICO 图标」。

尺寸是单选,六档:16×16、32×32、48×48、64×64、128×128、256×256,默认勾在 64×64。这一点值得单独说明,因为它是这个工具和大多数同类站最大的区别——它一次只生成一个尺寸的 ICO。后面会讲这意味着什么。

限制写在「需要注意」那一栏:图片小于 1 MB,格式为 JPG、GIF、PNG,建议长宽比 1:1。翻源码能看到这三条背后其实还多一层:除了文件大小,它还检查解码后的像素尺寸,超过 4096×4096 直接拒绝,理由是防止「图像炸弹」——一张几十 KB 的 PNG 解出来可能是几亿像素,GD 会直接把 PHP 进程的内存吃干。

页面上还有一行小字:「操作之前,您可先使用在线透明圆角工具,生成透明圆角图片,然后再进行操作」。也就是说圆角不是在转换时做的,而是先在旁边那个工具里把图处理成圆角带透明通道,再回来转 ICO。一个工具只做一件事,有点老派,但对单人维护的项目反而省事。

二、ICO 本来是「一盒图」,它只装了一张

ICO 不是「一张小图」的格式,它是个容器:文件开头一个目录,声明里面有几张位图、每张多大,后面依次是各张位图的数据。一张 ICO 里可以同时塞进 16、32、48、64、128、256 像素的版本,Windows 在显示时按当前缩放比例和场景自己挑最合适那一张——列表视图用小的,桌面快捷方式用 32,图标详情视图和高分屏用 256。

ICO 文件结构示意图:一个图标目录声明多张位图,按场景选择合适尺寸

有意思的是,这站的介绍文字自己也这么写:「一个 ico 文件实际上是多张不同尺寸图片的集合体」。但翻到 favicon.php 里,传给生成类的数组只有一个元素。

实现路径并不复杂:先生成一张 imagecreatetruecolor(尺寸, 尺寸) 的空画布,关掉 alpha 混合、开启 alpha 保存、用全透明色填底,再用 imagecopyresampled 把源图整张缩放到画布上;随后把这张画布塞进一个自写的 phpthumb_ico 类,由它按 ICO 规范拼二进制——文件头、目录条目、每张图的 BITMAPINFOHEADER、XOR 位图数据,再补一段 AND 掩码。

所以现状是:类本身支持多张图,但调用处只传了一张。结果是生成的 ICO 里只有你选的那一个尺寸。选 16 就是纯 16×16 的图标,在高分屏或者大图标视图下会被放大得发虚;选 256 则在只需要 16×16 的位置被系统缩小显示,文件也更大——因为它的输出是 32 位 BMP 式位图,没有走 PNG 压缩,256×256 那一档的体积会明显比同类工具大。

这不是致命缺陷,但用之前必须知道:如果你需要一个同时含多尺寸的 favicon,这站给不了,得换工具或者手工合成。反过来,如果你只是给老系统补一个 32×32 的 favicon.ico,或者某个只认 ICO 的软件要求固定尺寸图标,那它刚好够用,而且比装一堆依赖的图形工具省事。

三、代码里有几处写得比教程细致

虽然只有两个 PHP 文件,但安全处理做得比很多同类小工具认真:

位置做法挡住了什么
文件类型判断用 finfo 读真实 MIME,不看请求头把 PHP 文件改名成 .png 传上去执行
体积限制上传超过 1,024,000 字节直接拒绝大文件拖垮内存
像素限制getimagesize 超过 4096 拒绝图像炸弹(小文件、巨像素)
解码失败三种格式分别 @imagecreatefrom*,返回 false 就报错损坏文件导致的半成品输出
下载响应application/octet-stream 加 attachment,文件名固定 favicon.ico浏览器把结果当页面渲染

透明背景也处理得对:imagealphablending(false) 配 imagesavealpha(true),再用 imagecolorallocatealpha 填一层全透明底色,缩放后不会出现黑边或者白底。32 位输出里的 alpha 通道换算成 AND 掩码,这也是老式 ICO 能正确显示半透明的前提。

四、自建:一台 Ubuntu 加一套 nginx 配置

README 给的部署路径是标准 LNMP 套路:装 PHP、PHP-FPM、GD 扩展和 nginx,把仓库克隆到站点目录,把配置丢进 conf.d 重载。仓库里给了两套完整配置,非 HTTPS 与 HTTPS 各一份,区别只在证书与 301 跳转。

配置项值为什么这么设
请求限流同 IP 每分钟 30 次,突发 10图片转换吃 CPU,防止被脚本刷爆 PHP-FPM
上传体积client_max_body_size 2m页面限 1MB,这里留一倍余量给表单开销
超时body / header / send 均 10 秒转换是同步阻塞的,拖太久没意义
安全响应头nosniff、SAMEORIGIN、Referrer-Policy防上传文件被当脚本执行、防点击劫持
隐藏文件location ~ /\. 全部 deny挡住 .git 之类目录被直接下载
PHP 转发unix socket,版本要对应示例写的是 php7.2-fpm.sock,装 8.x 就得改

README 末尾还专门提醒了一个 502 的坑:nginx 主配置里的 user 默认是 nginx,而 PHP-FPM 通常跑在 www-data 下,两者对不上就 502 Bad Gateway,改成 www-data 即可。查日志能看出来,但知道答案能省半小时。

五、三个前提说清楚

没有许可证文件。README 自称「免费开源」,源码也都能拿到,但仓库里没有 LICENSE,法律上默认保留所有权利。自己搭来用没问题;要改一改再对外分发、或者集成进商业产品,最好先联系作者确认,别默认它是 MIT。

界面是 2019 年的审美。表格布局、系统默认按钮、没有拖拽上传、没有预览。它是工具,不是产品。介意观感的话改起来也不难,一个 index.php 加一点 CSS 的量级。

缩放质量取决于 GD 的重采样。大图缩到 16×16 时边缘容易发虚,这是位图缩放的固有损耗,不是 bug。要精细控制,最好在设计软件里先做好各尺寸版本;这个工具负责「快速可用」,不负责「像素级把控」。

六、什么情况下值得自建

偶尔做一个 favicon,用演示站或者随便找个在线工具,三十秒的事。但如果你经常给不同站点配图标、不想把客户品牌图传到第三方、或者手上有一台常年跑着 nginx 的机器——把它丢上去,一次配置,之后是常驻的私有工具,顺手还能改成团队内部的图标生成入口。

它解决的从来不是技术难题,而是「别为了一个十几 KB 的图标去看广告、开会员、把图传给别人」这点体面。至于多尺寸 favicon 这种正经需求,它确实覆盖不到,得另找工具——用之前知道这条边界就行。


本文整理自公开资料并重写:项目仓库 README(功能说明、nginx 配置示例、部署注意事项)、index.php 与 favicon.php 源码(尺寸映射、GD 缩放与 ICO 二进制打包逻辑、上传校验分支)、仓库元信息(星标、fork、建仓与提交时间、语言、许可证状态)以及演示站实际界面。仓库数据截至 2026 年 11 月,具体数值以 GitHub 页面为准。配图一张为演示站界面截图(渲染后仅隐藏悬浮按钮,未涂抹像素),一张为依据 ICO 文件格式自绘的结构信息图;仅做格式统一、去元数据与尺寸压缩。页脚署名、外链工具入口、更新时间提示均未收录。

本文整理自公开资料并做重写,原始出处:https://github.com/Nyaasu66/ico-transform-online。文中配图已去除站点叠加水印与推广信息;版权归原作者所有。

Last modification:November 11, 2026
如果觉得我的文章对你有用,请随意赞赏