使用方法
- 点「选择本地图片」挑一张图,PNG、JPEG、WebP、GIF、BMP 都能读。图片只在你自己的浏览器里解码,没有任何上传请求。
- 载入后结果区会显示原始尺寸(来自图片自身的像素宽高),宽度框和高度框也会被自动填成原始值,方便你在原图基础上改。
- 目标宽度默认 1920、目标高度默认 1080,这就是本页的示例值。两个框都只接受 1~65535 的整数。
- 保持「锁定原始比例」勾选,你只改宽度,高度会按原图比例自动算出来;取消勾选后可以分别指定宽和高,此时画面会被拉伸或压扁。
- 在导出格式里选 JPEG、PNG 或 WebP。选 JPEG、WebP 时下面的画质滑块生效,默认 0.92;PNG 是无损格式,滑块对它不起作用。
- 点「按当前尺寸导出」,浏览器在本地重采样后直接触发下载,文件名会自动带上目标尺寸。
这个图片尺寸调整工具能解决什么问题
一是上传前的体积与边长限制。手机原图 4000×3000 是 1200 万像素,解码后光是 RGBA 缓冲就要 45.78 MiB;很多后台上传口限边长 1920、限体积 2 MiB。先缩到 1200×900,像素数降到 108 万,面积只有原来的 1/11.11,再配合 JPEG 0.92 的画质,绝大多数场景一次过限。
二是统一一批素材的基准宽度。商品图、封面图、文档插图混在一起时,尺寸参差不齐会让排版跳动。把宽度统一到 1600 或 1920,高度按比例跟随,版式立刻整齐。
三是给高分屏做 2 倍图。同一条视觉稿需要一倍图和两倍图两份时,先导一份 640 宽,再导一份 1280 宽即可,两份共用同一个构图,不需要重新设计。
四是控制浏览器的解码内存。一张 8K 全景 7680×4320 是 3317 万像素,RGBA 缓冲 126.56 MiB,在内存紧张的设备上会明显吃力;把它缩成 1920×1080,内存占用直接掉到 7.91 MiB。
本页的图片尺寸调整只改像素总数,不改画面构图:不会把边缘切掉,不做旋转、调色、加字,也不做批量队列。一次处理一张,用完即走。
缩放原理:drawImage 九参数重载与分步减半
重采样发生在 CanvasRenderingContext2D.drawImage() 的九参数重载里。这个重载的签名是 drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh):前四个参数 sx, sy, sw, sh 在源图上框出一个矩形,后四个 dx, dy, dw, dh 把这块矩形画到画布的目标矩形里。缩放的实现就是把 sw, sh 设成原图宽高、dw, dh 设成你要的目标像素。缩小时一个输出像素会盖住源图上好几个像素,浏览器必须把它们合成一个,这一步叫重采样,也是画质分野的真正战场。
第二个关键参数是 imageSmoothingQuality。它有 low、medium、high 三档,前提是 imageSmoothingEnabled 为 true(规范默认就是 true,但显式写出来更稳妥)。在 Chromium 里这三档对应三种插值核:low 是双线性插值(每个输出像素看源图 2×2 邻域),medium 是双三次插值(4×4 邻域),high 是接近 Lanczos 的多抽头插值。抽头越多边缘越干净、代价是耗时上升,单张图完全值得选 high。
为什么大幅缩小不能一次到位。浏览器的快速缩放路径里,采样窗是固定大小的。把 4000 宽一次缩到 500 宽(1/8),每个输出像素只从源图 2×2 的窗口取样,剩下六十多个被跨过的像素直接丢弃,高频细节就变成摩尔纹和锯齿。稳妥做法是分步减半:每次只缩一半,让采样窗始终覆盖全部输入像素;1/2 连做三次等价于 1/8,但抗锯齿效果差很远。本工具的判据是「当前边长还大于目标的两倍就再减半」,因此 4000×3000 缩到 1200×900 需要 2 次 drawImage(4000×3000 → 2000×1500 → 1200×900),缩到 400×300 需要 4 次,缩到 200×150 需要 5 次。
EXIF 方向是最容易被忽视的坑。相机和手机竖着拍的照片,像素数据往往是横的,靠 EXIF 里一个叫 Orientation 的字段记录「该转多少度」。这个字段共有 1~8 八种取值,覆盖正常、水平镜像、旋转 180°、垂直镜像,以及 90° / 270° 的旋转加镜像组合,手机竖拍最常见的是 6 和 8。用普通的 new Image() 加载再画到画布上,部分路径不会应用这个标记,导出的图就会躺倒。稳妥写法是 createImageBitmap(blob, { imageOrientation: 'from-image' }),让解码器在解码阶段把像素摆正,再交给 drawImage;本工具优先走这一条,旧浏览器才退回 Image 元素。
画布本身有硬上限,超了不会报错。Chromium 的画布单边最大 65535 像素,总面积上限是 2 的 28 次方 = 268435456 像素,约等于 16384×16384。传给 canvas.width / height 的乘积一旦越界,浏览器不抛异常,而是静默给出一张空白图——这是最容易被误判成「工具坏了」的一类问题。所以本页在算目标尺寸时会先做面积校验并给出明确提示。
最后是导出接口的取舍。toDataURL() 是同步的:它在主线程上跑完整编码器,再把二进制转成 base64 文本返回。base64 比原二进制大 4/3,也就是多出 33.33%,一张 500000 字节的 JPEG 会变成一个 666668 字符的字符串,大图时足以让页面卡住。toBlob(callback, type, quality) 是异步的,直接把 Blob 交回来,既省掉 base64 膨胀,也不会长时间占住主线程,所以本工具用它导出。
完整示例(数值仅作演示)
页面打开时的默认条件是:目标 1920×1080、导出格式 JPEG、画质 0.92、勾选「锁定原始比例」。图片尺寸调整的默认结果就是下面这一组数字,其中 1920×1080 同时也是对照表里的一行,两处一致。
- 默认目标 1920×1080 = 2,073,600 像素,未压缩 RGBA 缓冲 8,294,400 字节 = 7.91 MiB;
- 同样按 RGBA 算,640×360 只有 230,400 像素、0.88 MiB,前者是它的 9 倍;
- 手机常见的 4000×3000 照片是 12,000,000 像素,RGBA 缓冲 45.78 MiB;
- 缩到 1200×900 后剩 1,080,000 像素,面积是原来的 1/11.11,边长是原来的 1/3.33;
- 这一趟缩放跑 2 次 drawImage:4000×3000 → 2000×1500 → 1200×900;
- 8K 全景 7680×4320 是 33,177,600 像素、RGBA 126.56 MiB,缩到 1920×1080 后内存只剩 7.91 MiB。
再看一条边界示例:目标填成 20000×20000 时,面积是 400,000,000 像素,已经超过 268,435,456 的上限,超限约 49%,本页会直接拦下来并写清超了多少,而不是给你一张空白图。
输入范围、画布上限与分辨率对照表
下表把常见分辨率换算成像素数与 RGBA 缓冲体积。RGBA 缓冲 = 宽 × 高 × 4 字节,是图片被解码进内存后的真实占用量,和文件体积不是一回事——一张 500 KB 的 JPEG 解码后可能占好几十 MiB。
| 分辨率 | 像素数 | RGBA 缓冲 | 相对 1920×1080 |
|---|---|---|---|
| 640×360 | 230,400 | 0.88 MiB | 0.11 倍 |
| 800×600 | 480,000 | 1.83 MiB | 0.23 倍 |
| 1024×768 | 786,432 | 3.00 MiB | 0.38 倍 |
| 1280×720 | 921,600 | 3.52 MiB | 0.44 倍 |
| 1366×768 | 1,049,088 | 4.00 MiB | 0.51 倍 |
| 1440×900 | 1,296,000 | 4.94 MiB | 0.63 倍 |
| 1600×900 | 1,440,000 | 5.49 MiB | 0.69 倍 |
| 1920×1080(默认) | 2,073,600 | 7.91 MiB | 1.00 倍 |
| 2048×1536 | 3,145,728 | 12.00 MiB | 1.52 倍 |
| 2560×1440 | 3,686,400 | 14.06 MiB | 1.78 倍 |
| 3840×2160 | 8,294,400 | 31.64 MiB | 4.00 倍 |
| 4096×2160 | 8,847,360 | 33.75 MiB | 4.27 倍 |
点「加载更多分辨率」会补上更大的一档,点「导出 CSV」把当前可见的整张表存成带 BOM 的 CSV(Excel 打开不乱码),点「复制对照表」复制成制表符分隔的文本,可以直接粘进表格软件。
边界与精度说明
- 宽高都必须在 1~65535 之间。小于 1 的画布不存在;超过 65535 是 Chromium 的单边硬上限,写进去也只会得到空白图。两个框都只收整数,小数会被拒绝。
- 总面积上限 268435456 像素。即使两边分别都没超 65535,乘积超了同样会白屏。例如 20000×20000 = 400,000,000 像素已超限,而 16000×16000 = 256,000,000 像素仍在限内。
- 放大不会增加细节。把 500 宽的图拉到 2000 宽,插值只能把像素抹平,锐度不会回来。需要更大尺寸时请回到原始素材重新导出。
- 分步减半只对缩小生效。目标是放大时只做一次 drawImage,多跑几次没有任何好处,只会更慢。
- 输出不含 EXIF。canvas 画出来的位图只有像素,不携带原图的相机型号、拍摄时间、GPS 等信息。这对想看拍摄参数的人是损失,对在意隐私的人反而是好事。
- JPEG 没有透明通道。带透明背景的 PNG 导出成 JPEG 时,透明区域会变成黑色。需要保留透明请选 PNG 或 WebP。
- 画质滑块不是线性指标。0.92 与 0.80 在肉眼上差别很小,体积却能差三成左右;低于 0.5 才会出现明显色块。PNG 忽略这个滑块。
- 颜色配置不会被写入。导出的图默认按 sRGB 解释,原图若是 Display P3 等宽色域,缩放后可能看起来略淡,需要专业色彩流程请用桌面软件处理。
常见问题
图片会上传到服务器吗?
不会。文件通过 File 对象交给 createImageBitmap 在本地解码,重采样在你的浏览器里用 canvas 完成,导出走 toBlob。想自己确认,打开开发者工具的网络面板,选一张图并导出,全程不会有任何新请求。
为什么一次缩小会出现锯齿?
因为浏览器的快速缩放路径里采样窗是固定大小的,一次缩到 1/8 时每个输出像素只看得到源图 2×2 邻域,被跨过的像素全部丢掉,细密的纹理就会出现摩尔纹。改成每次减半、分步执行,采样窗始终覆盖全部输入像素,边缘和纹理就干净很多。
竖着拍的照片导出来为什么躺倒了?
因为像素数据本身是横的,方向记录在 EXIF 的 Orientation 字段里,共 1~8 八种取值。某些加载路径不会应用这个标记。本工具优先使用 createImageBitmap(blob, { imageOrientation: 'from-image' }),让解码器直接输出摆正后的像素,所以竖拍照片不会躺倒。
为什么导出的图小了很多,画质却看不出差别?
因为像素数少了,但每个像素仍是 24 位真彩色,只是用来表达细节的像素变少。1920 宽的图在 1920 宽的屏幕上是一比一显示,不会放大,肉眼看不出损失;只有当你再把它放大,或者打印到 A3 以上,才会看出差距。
PNG 和 WebP 怎么选?
要保留透明通道又不想有损压缩,选 PNG;要体积最小、可以接受有损,选 WebP,同样画质下通常比 JPEG 再小两三成,Chromium、Firefox、Safari 14 以后都能打开。只有在意最广泛的兼容性时才回退到 JPEG。
能一次处理很多张吗?
不能。这个图片尺寸调整工具刻意做成一次一张:重采样是 CPU 密集操作,批量跑容易把标签页卡住,也容易在导出到一半时丢失命名对应关系。多张素材的批量需求建议用桌面端的图像处理软件。
目标尺寸填得很大时为什么提示超限?
因为画布有面积硬上限 268435456 像素(约 16384×16384)。超过之后浏览器不会报错,而是给你一张空白图,非常难排查。本页提前校验,会在提示里写清你填的乘积、上限是多少、超了多少,方便你直接改小。
缩放之后的图还能看到拍摄信息吗?
看不到。canvas 输出的是纯像素位图,EXIF 里的相机型号、镜头、光圈、快门、ISO、拍摄时间和 GPS 坐标都不会带过去。如果你需要保留这些信息,得用会写回 EXIF 的桌面软件处理。
相关工具
- 图片压缩工具:只压体积不改像素,适合已经在目标尺寸、只想把文件变小的情况。
- 图片格式转换:在 PNG、JPEG、WebP 之间换格式,尺寸保持不变。
- 缩略图生成:把大图快速做成小尺寸索引图,偏列表展示场景。
- PNG转WebP转换器:专门处理 PNG 到 WebP 的转换,适合给网页做首屏优化。
- 旋转图片在线:需要按角度旋转或做镜像时用,它只改方向不改像素总数。
- favicon生成器:一次产出多种小尺寸图标,本质是同一套缩放逻辑的批量分支。
- 模糊图片在线:做背景虚化或打码时用,和缩放是两类不同的像素运算。
- 图片工具:查看全部图片工具。