Javascript-如何将图像缩小到特定的文件大小? [英] Javascript - How to reduce image to specific file size?

查看:129
本文介绍了Javascript-如何将图像缩小到特定的文件大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将图像上传到服务器之前,我正在使用Base64对图像进行编码.我需要将其文件大小减小到特定大小(500kB).我试图获得原始文件和所需文件大小之间的比率,并相应地减少高度和宽度.但这是行不通的.有帮助吗?

I am encoding my images in Base64 before uploading them to the server. I need to get their file sizes down to a specific size (500kB). I have tried to get the ratio between the original and the desired file size and reducing de height and width accordingly. But it does not work. Any help?

推荐答案

我遇到了与您相同的问题,在将图像上传到服务器之前,我需要调整图像的大小.所以我的第一个想法是计算像素数以确定字节数.但是很快我注意到大多数图像格式都使用压缩.例如,只有白色像素的1000x1000图片仅是正常图像尺寸的一小部分.因此,这就是为什么我认为很难将任何尺寸预先计算为字节数的原因.因此,我使用了二进制搜索算法来尝试查找应用于减小宽度和高度的百分比.该图像将被多次调整大小以找到理想的百分比,因此效率不高,但我想不出其他任何方法.

I had the same problem as you, I needed to resize an image before it was uploaded to my server. So my first thought was to calculate the number of pixels to determine the number of bytes. But very quickly I noticed that most image formats use compression. For example, a 1000x1000 picture with only white pixels will only be a fraction of the size of a normal image. So that’s why I think it’s hard to pre-calculate any dimensions into the number of bytes. So I used the binary search algorithm to try and find the percentage that should be used to reduce the width and height. The image will be resized multiple times to find the perfect percentage so it’s not very efficient but I couldn’t think of any other way.

// maxDeviation is the difference that is allowed default: 50kb
// Example: targetFileSizeKb = 500 then result will be between 450kb and 500kb
// increase the deviation to reduce the amount of iterations.
async function resizeImage(dataUrl, targetFileSizeKb, maxDeviation = 50) {
    let originalFile = await urltoFile(dataUrl, 'test.png', 'image/png');
    if (originalFile.size / 1000 < targetFileSizeKb)
        return dataUrl; // File is already smaller

    let low = 0.0;
    let middle = 0.5;
    let high = 1.0;

    let result = dataUrl;

    let file = originalFile;

    while (Math.abs(file.size / 1000 - targetFileSizeKb) > maxDeviation) {
        const canvas = document.createElement("canvas");
        const context = canvas.getContext("2d");
        const img = document.createElement('img');

        const promise = new Promise((resolve, reject) => {
            img.onload = () => resolve();
            img.onerror = reject;
        });

        img.src = dataUrl;

        await promise;

        canvas.width = Math.round(img.width * middle);
        canvas.height = Math.round(img.height * middle);
        context.scale(canvas.width / img.width, canvas.height / img.height);
        context.drawImage(img, 0, 0);
        file = await urltoFile(canvas.toDataURL(), 'test.png', 'image/png');

        if (file.size / 1000 < (targetFileSizeKb - maxDeviation)) {
            low = middle;
        } else if (file.size / 1000 > targetFileSizeKb) {
            high = middle;
        }

        middle = (low + high) / 2;
        result = canvas.toDataURL();
    }

    return result;
}

function urltoFile(url, filename, mimeType) {
    return (fetch(url)
            .then(function (res) {
                return res.arrayBuffer();
            })
            .then(function (buf) {
                return new File([buf], filename, {type: mimeType});
            })
    );
}

https://jsfiddle.net/qnhmytk4/3/

这篇关于Javascript-如何将图像缩小到特定的文件大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆