通过canvas压缩图片大小和质量之间的关系

通过canvas压缩图片大小和质量之间的关系

近期项目需要对用户上传的大图片压缩后生成一个缩略图,防止列表展示时加载过于缓慢。预计对大于100KB的图片进行压缩,生成一个50KB一下大小的缩略图。使用的方法就是通过<canvas>标签进行重新绘制、生成压缩文件。不多说,上代码

<body>
    <!-- 隐藏input -->
    <input type="file" id="input" title="file" placeholder="file" hidden />
    <!-- 上传按钮 -->
    <button type="button" id="button">点击上传</button>

    <script>
        const fileInput = document.querySelector('#input'),
            button = document.querySelector('#button');
        button.addEventListener('click', () => {
            fileInput.click();
        });
        fileInput.addEventListener('change', () => {
            button.disabled = true;
            const file = fileInput.files[0], map = {};
            // 原文件大小
            console.log('origin file \t', file.size + 'B \t');
            // 生成<img>对象
            const img = new Image();
            img.src = URL.createObjectURL(file);
            // 加载后用canvas重画
            img.addEventListener('load', () => {
                const canvas = document.createElement('canvas');
                canvas.width = img.width;
                canvas.height = img.height;
                const ctx = canvas.getContext('2d');
                ctx.drawImage(img, 0, 0);
                // 生成100个质量在0.1 - 1之间的不同图像并将quality和size写入map
                for (let i = 100; i > 0; i--) {
                    canvas.toBlob(blob => {
                        const newFile = new File([blob], 'image.jpeg', { type: 'image/jpeg' });
                        map[i] = newFile.size;
                    }, 'image/jpeg', i / 100);
                }
            });
            // 执行完毕后打印文件大小数列
            const interval = setInterval(() => {
                console.log(Object.keys(map).length);
                if (Object.keys(map).length === 100) {
                    console.log(Object.keys(map));
                    console.log(Object.values(map));
                    button.disabled = false;
                    clearInterval(interval);
                }
            }, 1000);
        });
    </script>
</body>

通过3个不同的jpeg图片测试,结果如下图:
在toBlob()quality设置为94%以上时,甚至会出现canvas文件大于源文件的情况
可以看到,在quality > 80的情况下,图片文件大小增速明显变快。所以可以重复drawImage() + toBlob(f, t, 0.78)这个过程,直到文件大小小于50KB

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值