两个框为什么会在同一张图上互相打架
一张自造的 1237×859 纯色图(非照片)拖进去,锁着时把宽打 800,高框写回 "556";再把高框手打成 300,它又变回 "556"。滑杆那头:同一张 PNG 缩到 619×430,质量从 10 拖到 100,四轮结果行都是 "619 × 430 | 6.8 KB"。这页模板 12308 字节 / 265 行,脚本原样跑两路:node:vm 桩与 Chrome 154 真编码器。
被测的是图片尺寸调整,全页本地处理,grep fetch( 命中 0 处。
锁只读宽、只写高
onSizeInput(L188–L192)锁着时只读宽框、只算 Math.round(宽 / aspectRatio)、只写高框。aspectRatio 存的是 1237/859=1.440046565774156 这个浮点商,不是既约比,于是手打的高必被覆盖:宽 800 + 手打高 300 → 高框留 "556"。toggleLock(L181–L185)解锁后两框各走各的。
| 锁着时宽框 | 高框 | 除法原值 |
|---|---|---|
| 859 | 597 | 596.5084882780922 |
这把尺在原图上共扫 18 档(1237→"859"、400→"278"),宽打 1 时靠进位保住高 1。
百分比是两把独立的尺
onPercentInput(L195–L200)对宽高各跑一次 Math.round,完全不看 aspectLocked。pct=50 → 619×430,理想 618.5 × 429.5,两框之和 1049 对 1048、差 1。两轴同时以 .5 结尾的 p 有 10 档,Math.round 对正 .5 一律进位;pct 从 1 扫到 1000,120 档两条路的高不等。
图 1:pct=1 那档两条路给出两种长宽比。
比例框从不回头读宽高框
switchMode(L172–L178)只改 currentMode 与两个面板的 display,没有任何一行代码回写 resize-percent。点 150% → 切回 pixel → 把宽手打 400(高被算成 278),比例框全程仍显示 "150";反推值 100*1856/1237=150.0404% 不等于框里的 150——框里存的是「点过的档」。再点一次 setPercent(150)(L203–L206)就把两框打回 1856×1289,刚手打的 400 蒸发。
滑杆在 PNG 上为什么一个字节都不动
本机 Chrome 154 只有三个真编码器,1×1 画布上 png / jpeg / webp 分别回 110 / 762 / 552 B。L229 把滑杆值除 100 交给 toBlob,PNG 编码器不吃这个参数;BMP 又叠一层——L228 把输出改写成 PNG,而 L152 只给 image/jpeg / image/webp 显示质量行,滑杆本身 display:none。
| 619×430 的 blob | q10 | q50 | q90 | q100 |
|---|---|---|---|---|
| PNG | 6971 | 6971 | 6971 | 6971 |
| JPEG | 2338 | 2340 | 2341 | 3921 |
| WEBP | 1092 | 1102 | 1050 | 4684 |
JPEG 的 10→90 三档只差 3 B;WEBP 的 q90 比 q10 小(1050<1092),编码器不保证单调;BMP 源(3188662 B)六档全 6971 B。同族几页共用这一份模板,那几页的字节账不在本篇。
结果行那串字面怎么拼
L235 是 w + ' × ' + h + ' | ' + formatSize(blob.size),w/h 取 JS 里的整数而非画布属性," × " 是 3 码元/4 字节。formatSize(L165–L169)分三档:B 档原样整数、KB 档 toFixed(1)、MB 档 toFixed(2),阈值 1024 与 1048576,实测 1024→"1.0 KB"、1075→"1.0 KB" 而 1076→"1.1 KB"、1048576→"1.00 MB"。压字节走另一条通道,见图片压缩;那篇透传的实测量的是别一页。
三闸与它拦不住的那些
doResize(L209–L237)只三道闸:无图、parseInt 出 NaN 或 ≤0、w>10000 || h>10000;JS 不设下限校验,min="1" / max="10000" 只是控件属性:"10001" 浏览器不拦,走到 L216 才弹「尺寸不能超过 10000px」。最安静的是 "1e5":parseInt 遇 e 停读成 1,无 toast 真出图,结果行 "1 × 1 | 762 B",输入与产出差 5 个数量级。只有滑杆被浏览器硬夹(打 9 → "10"),L229 因此落在 10..100。
失败之后屏上留着的是上一张
出过 "1 × 1 | 762 B" 之后再打 w=619 / h=0,弹「请输入有效的宽高尺寸」,结果行仍读上一句。更实在的是不落地那格:先出 619×430 的 webp("619 × 430 | 1.0 KB"、1050 B),再打 10000×10000 的 webp:回调不来,画布属性却已被 L221–L222 同步改成 10000x10000,结果行仍是上一句、下载仍是上一档那 1050 B。resetAll(L253–L263)之后七个状态量逐字不变。
批量是实测出来的「没有」:files.length 0 处、for( 0 处、progress 0 处,两处 files[ 只取 [0];一次拖入 2 个文件只有第 1 张进 handleFile。重采样算法与 imageSmoothingQuality(页面从不读它,无像素级判据可反推核函数)、队列与耗时(无队列代码即无对象可测)、界面渲染像素(无渲染器判据),一律标未实测。
顺带对一眼文案
config/tools.php 的 image-resize 条目 16 条主张逐条判:[一致] 6、[部分一致] 7、[冲突] 3。冲突三条:「另一边」只对一半、「证件照」档锁着时输入 295 得 205 而不是 413(差 -208,要先解锁而文案未提)、「缩略图批量」零通道。
常见问题
Q:锁着时手打高度为什么被打回?
锁只在宽→高一个方向写,手打值在回写那一步被覆盖。
Q:pct 50 得 619×430,是等比吗?
它是宽高各过一次 Math.round:619/430=1.4395348837209303 对源比差 -0.0355%,1..1000 里 120 档与锁尺不等。
Q:滑杆拉满为什么字节没变?
PNG 与被 L228 改写成 PNG 的 BMP 不吃 quality,四轮同字面;只有 JPEG / WEBP 变字节。