资讯动态

canvas导出空白图怎么检测?三内核只有toBlob一致

发布时间:2026/10/5 19:41:08 来源:尧图企业网站定制
我那个小工具站的上传组件会先在浏览器里缩图再上传。它一直没设像素上限。前阵子我想弄清一件事用户真传一张 1 亿像素级的图过来这段代码会不会出错、我又能不能知道它出错了。我拿脚本造了一批合成大图并测了三个内核Chromium 149 开源构建不是日常那个 Chrome、WebKit 26.5 构建和 Firefox 151 构建。WebKit 和 Firefox 这两个构建也跟 Safari、正式版 Firefox 不是一回事。样本全是程序生成的渐变加色块加噪声不是照片。之所以非要在前端解决是因为图不经过我的服务器带宽就不花钱。动手前我先拿现成工具对照过这条路走不走得通。我用的是图映 ImgInghttps://imging.cn/的压缩转换把 10000×10000 的合成 JPEG 转成 WebP 和 JPG。三个内核一共 12 个用例我数了网络记录里的非 GET 请求0 次。1 亿像素这一档在浏览器本地是能处理完的。我真正想知道的是再往上走会发生什么。跑完最让我意外的是超了上限以后大部分 API 都装作没事。canvas 超过像素上限会报错吗前两步不会。Chromium 149 和 WebKit 26.5 构建的画布面积上限都是 268,435,456 像素16384×16384 能画能导出16384×16385 就不行。Firefox 151 构建能画到 23168×23168。我拿刚过线的尺寸去试getContext(2d)三家都照样返回对象width和height读回来也是原值。我把画布一路加到 10 亿像素它还是返回对象。整幅fillRect同样不抛错。代码走到这里全是绿灯而画布上其实什么都没有。再往下读像素三家就分岔了。Chromium 和 WebKit 的getImageData返回全 0 且不报错。在这一步抛NS_ERROR_FAILURE的 Firefox 反倒是最老实的一个。isContextLost()也靠不住Chromium 返回 true 并触发contextlost事件。WebKit 构建压根没有这个方法而 Firefox 返回 false。控制台只有 WebKit 打了一句「Canvas area exceeds the maximum limit」。Chromium 和 Firefox 一个字都没有。导出空白图时哪个信号三家一致只有导出这一步。toBlob三家都回调 nulltoDataURL三家都返回data:,这 6 个字符。我原来的组件拿到 blob 就直接进上传队列从没判过空。照那个写法null 会在读blob.size那一行抛类型错误。用户看到的只是按钮转了一下没反应。我写的这个复现小页面照老组件的写法没判空。WebKit 26.5 构建里预览和 380×380 的缩略画布都有图红框里按原尺寸导出的 export.jpg 却只有 4 bytes。toBlob回调的 null 被直接塞进new File()写进去的就是 null 这 4 个字符。接着进上传队列的话传上去的也是它。OffscreenCanvas 的convertToBlob更容易误导人。Chromium 149 超限时 reject 的是IndexSizeError。错误信息说画布尺寸为 0可同一时刻画布宽高读回来明明是 16384×16385。我第一次看到还以为是自己哪里把宽高清零了。翻了一遍代码才确认错误信息和真实原因对不上。怎么检测读回角落像素再判 toBlob我现在分三道。画之前先比面积宽×高超过 268,435,456 就不在 Chromium 和 WebKit 上硬画直接走缩图。画完读回一个已知像素Firefox 会在这里抛错另两家会读到 0。导出后再判回调是不是 null。读回哪个像素有讲究。WebKit 构建单边能画到 4,194,303 px。宽度再多 1 px 时左上和中心读回都对只有右下是 0。我第一版只读中心点这种情况就被判成了成功。后来改成读右下角那一个像素。复现页把两张画布整幅填红后把左端、中间、右端各放大显示。上面宽 4,194,303 的三段全红。下面只多 1 px 的那张左端和中间照样全红。红框里右端最后那一列是空的露出底下的棋盘格。只读中心点的话这张画布会被当成画好了。还有一块我没底。我测的全是这几个开源构建。真 Safari、iOS 和正式版 Chrome 我一台都没测。手机上的上限是多少我不知道。面积常量我只敢当兜底。真正拦住空图的还是导出后那一下判空。你的上传组件如果也在前端缩图先找到调toBlob的地方看回调里有没有判 null。再拿一张超过 16384×16384 的合成图喂进去试一次。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑