在这个快速教程中,我们将使用JavaScript压缩带有文件输入元素的图像。我们将压缩图像并将它们保存回文件输入,以便上传。
为了确保用户可以上传图片,并防止超大图片被上传,我们可以在上传前压缩图片数据,而不必向用户提出各种要求。
如果您赶时间,或者觉得阅读代码本身更方便,可以跳转到这里的最终代码片段。
获取选定的图像文件
在下面的示例中,我们将接受所有类型的文件,但只压缩图像。multiple
属性允许选择多个文件。
为了防止添加其他文件,我们可以将文件输入接受属性设置为 image/*
。
让我们设置一个文件输入框,当用户选择了一个或多个文件时,我们将侦听 change
来检测。我们将在下一节处理 TODO
项目。
现在,当用户选择一个或多个图像文件时,我们的代码就会运行。接下来是压缩图像。
压缩图像
我们将实现 compressImage
函数。该函数将把传递的文件对象转换为 ImageBitmap
,并将其绘制到 元素中,然后画布将使用 toBlob API 返回压缩后的 JPEG。
请注意,我们也可以要求WEBP,但这(在撰写本文时)在 Safari 上不支持♂️
让我们开始吧。
现在,compressedFile
变量将包含压缩后的图像文件。
接下来就是将压缩后的图像文件(以及忽略的文件)保存回文件输入端。
将压缩图像保存回文件输入端
我们将创建一个 DataTransfer
对象,用它来创建我们的新文件列表。之后,我们可以将该列表保存回文件输入端
DataTransfer
对象只接受 File
对象,因此我们需要将 Blob 转换为文件,让我们更新 compressImage
函数。
总结
我们已经学会了如何使用 canvas 和 DataTransfer 来设置一个不起眼的小脚本,帮助我们在上传前压缩图片。该脚本将使我们的用户更容易上传图片。
当然,我们还有很多需要改进的地方,例如,我们可以
- 调整图像大小以适应最大边界框。
- 将图像裁剪成一定的长宽比。
- 更好地处理错误输入并显示合适的错误信息。
- 确保我们能处理 Safari 内存问题。
如果我们需要一个更强大的解决方案,我们可以使用 FilePond 来处理文件上传,它可以调整图像大小、压缩等。
如果我们需要更多的控制,我们可以使用 Pintura 让用户在上传前编辑图片,Pintura 也可以直接替代我们的 compressImage
功能。