几个月前,一位开发者需要为Shopify店铺转换400张产品图片,从JPG格式转为WebP格式。他试了市面上常见的在线转换工具,结果发现每一个都要求先把文件上传到服务器,排队等待处理,再下载一个ZIP压缩包。有的免费版会打水印,有的限制只能转换10张,超过就要付费。
400张图片走这个流程,体验相当痛苦。但真正让他介意的环节是上传——这些都是产品照片,他不想让这些图片留在别人的服务器上,哪怕只是临时存放。
于是他做了一个叫BatchSet的批量图片转换工具,完全在浏览器里运行。不上传、不注册、无水印。拖入图片,本地完成转换,下载ZIP即可。
浏览器端的处理管线
现在的浏览器能做的图像处理工作,比很多人想象中要多。BatchSet的核心流程是这样的:用户拖入文件,FileReader把文件读取为ArrayBuffer,createImageBitmap在Web Worker里完成解码,OffscreenCanvas绘制并编码为目标格式,JSZip打包所有文件,最后自动下载ZIP。
大部分人在做图片处理时,仍然习惯用new Image()或者canvas.drawImage()配合源图片。这种方式能用,但它跑在主线程上,会阻塞界面交互。
createImageBitmap不一样。它在主线程之外完成图片解码,返回一个ImageBitmap对象,你可以直接把它绘制到任意canvas上,不需要重新解码。
速度方面,一张典型的2MB产品照片,解码耗时约20到40毫秒。真正的优势在于它不阻塞UI线程,所以即使一次处理几百张图片,进度条也能保持流畅。
并行处理的关键
解码完成后,需要把图片编码为目标格式。输出WebP、JPG或PNG时,把bitmap绘制到OffscreenCanvas上,然后调用convertToBlob。
OffscreenCanvas可以在Web Worker内部工作,所以重编码工作——尤其是大图或高质量输出——不会让标签页卡死。
真正的性能提升来自多Worker并行。BatchSet使用navigator.hardwareConcurrency获取逻辑CPU核心数,为每个核心生成一个Worker,图片按轮询方式分配到各个Worker。在一台8核的现代笔记本上,这意味着8张图片可以同时处理。
这种纯客户端架构的取舍很明确:隐私性拉满,用户的图片数据完全不出设备;但代价是处理能力受限于本地硬件,超大图片或极高分辨率输出时,内存占用会明显上升。
热门跟贴