返回博客
开发者日记2026 年 4 月 4 日7 分钟阅读

我拒绝每月花 10 美元买放大器,于是直接在浏览器里做了一个

完整复盘:多步 Canvas 插值的原理、Instagram 九宫格的每格像素账、上线前修过的三次真实移动端崩溃,以及插值放大做不到什么的诚实说明。

促使我做这个功能的,是一张 1600×1600 的裁剪图。我想把它切成 Instagram 3×3 九宫格,账一算很残酷:1600 除以 3,每格只有 533 像素;而 Instagram 方图按 1080 像素展示。也就是说每一格都会被 Instagram 自己的压缩器强行放大——正是那种「我的九宫格怎么发出去就糊了」的效果,这个网站存在的意义就是避免它。

我去找放大工具,试过的每一个不是躲在 9.99 美元/月的付费墙后面,就是让我排在其他用户后面等队列, 要么直接在结果上盖水印。而这件事的本质,不过是一次我的笔记本一秒钟就能完成的重采样运算。

所以我把放大器直接做进了 9grid 的切图工具里。这篇文章是完整的复盘:它怎么工作、上线前在手机上崩了三次都是怎么修的,以及同样重要的——插值放大到底做不到什么。

先算清 Instagram 九宫格的像素账

放大之前先明确目标。9grid 每个切片按 1080 像素或更高导出,所以问题是:你的原图够不够喂饱每一格?

布局1080px 切片所需原图1600px 宽的照片实际每格
1×2 轮播2160px 宽800px——需要约 1.4 倍
1×3 轮播3240px 宽533px——需要约 2 倍
3×3 主页九宫格3240×3240533px——需要约 2 倍
3×4 拼图墙3240×4320533px——需要 2 倍以上

注意一个规律:几乎所有现实中的「救图」场景都落在 1.5–2 倍之间。这个约束决定了整个设计方向——我优化的是干净的 2 倍放大,而不是英雄主义的 8 倍重建。

它的工作原理:多次小步,而不是一步到位

在 9grid 里点「放大」时,图片全程不离开页面,缩放由浏览器的 Canvas API 完成——但不是一次drawImage 直接画到目标尺寸。一步跳到位的双线性插值会产生肉眼可见的糊边。9grid 的做法是每步最多放大 1.5 倍,反复叠加,直到到达目标。

有两个细节让结果明显好于朴素缩放。第一,每一步都开启浏览器的 imageSmoothingQuality: "high"提示,Chromium 内核会启用更好的重采样核。第二,多次小步插值的叠加效果远比单次大步更接近真正的 Lanczos 滤波——和 Photoshop 时代「每次放大 10%」的老技巧是同一个原理。一次 4 倍放大实际上被拆成五次约 1.32 倍的小跳。

每步之间用 requestAnimationFrame 把控制权交还浏览器,避免两千万像素的画布重绘把页面卡死。另外,如果请求的放大不足 5%,9grid 会直接返回原图——为了不到 5% 的尺寸做一次重采样,纯属白白损伤像素。

上线前在手机上崩溃的三种方式

桌面版第一天就跑通了,然后移动端 Safari 花了一周教我做人。这三个修复至今都留在代码里:

1. iOS 的画布上限

iOS Safari 对约 1670 万像素以上的画布会静默失败——不报错,直接给你一张黑图。手机 1200 万像素照片放大 4 倍远超这个上限。现在 9grid 在移动端把输出钳制在 1200 万像素(桌面 2500 万),并如实告诉你实际生成的尺寸。

2. toDataURL 冻屏

最早的导出用的是 canvas.toDataURL()——一个在主线程上同步拼 base64 字符串的调用。大画布下这个字符串有几十 MB,中端手机直接冻死。换成异步的 toBlob()后彻底解决。

3. 被垃圾回收拖垮

每个 1.5 倍小步都新建一个画布,几步下来给垃圾回收器堆了几百 MB。现在改为两个画布交替充当源和目标,无论放大要跳多少步,内存都保持平稳。

插值放大老实说做不到什么

这是大多数放大器落地页不会写的部分。Canvas 插值只是重新分配你已有的像素,不会凭空发明你没拍到的细节。一张 500px 的人脸放大 4 倍,得到的是一张平滑、无瑕疵的 2000px 人脸——但不会变锐利。想要「无中生有」的细节(真正的 "enhance"),需要机器学习模型:要么下载几十 MB 的模型文件(刚好会压垮我前面救回来的那批中端手机),要么走服务器端处理(隐私和成本的代价又回来了)。

对 Instagram 九宫格这个场景来说,这笔账几乎总是偏向插值:

  • 你的缺口很小。上面表格已经说明,真实的九宫格工作流需要的是 1.4–2 倍——在这个区间,高质量插值和 ML 模型在照片上的差距几乎看不出来。
  • Instagram 反正要再压一遍。模型幻想出来的精细纹理正是它的压缩器最先抹掉的东西;能活下来的是干净的边缘和「没有放大糊」——这恰恰是插值给你的。
  • 随处可用、即点即得。不下载模型、不排队、不上传,照片全程留在你浏览器的内存里。

我的经验法则:原图达到目标尺寸的一半以上,就放心本地放大然后发;想把一张 300px 的缩略图变成海报,任何免费工具——包括我这个——都做不到,别信说能做到的。

完整工作流

把照片传进切图工具,选好布局,看尺寸提示:如果有切片会低于 1080px,9grid 会推荐放大倍数(缺口小推 2 倍,缺口大推 4 倍)。点「放大」,等进度跑完,再切图。整个弯路在普通笔记本上大约多花五秒。

来试试浏览器放大器

无需信用卡、无需注册、无水印——照片全程不离开页面。

打开 9grid

相关推荐