【问题标题】:How to find quality parameter in compressjs dynamically如何在compressjs中动态查找质量参数
【发布时间】:2022-01-10 19:48:39
【问题描述】:
我的文件大小是 500kb(它会动态地任意大小)。我的目标是 150kb。
由于某些原因,我只能选择质量
new Compressor(selectedFile1, {
quality: targetRatio,
即,如果我将 targetRatio 设置为 0.7,它将减少图像到 159kb~
为了动态找到目标比率,我所做的是
var targetRatio = fileSize / 150;
但是,我不知道如何找到 targetRatio 以获得准确的值,即减少到 150kb
Here's the place to test
【问题讨论】:
标签:
javascript
html
jquery
math
compression
【解决方案1】:
达到 150kb 修改质量,不适用于每张图片。
JPEG 压缩量通常以质量级别的百分比来衡量。 100% 质量的图像(几乎)没有损失,1% 质量是非常低质量的图像。一般来说,90%或更高的质量水平被认为是“高质量”,80%-90%是“中等质量”,70%-80%是低质量。
如果您使用 15.594 x 3.936 jpg (example),根据存储的信息可能约为 2.5mb,您将无法达到 150kb 的 jpg 格式。
因此,目标 150kb 将是 150.000 / 2.500.000 = 0.06。
从屏幕截图的结果大小可以看出,这是不可能的,您必须进行多次转换并通过减小宽度和高度来测试结果大小是否恰好等于或低于 150kb。但是使用 0.06 的质量压缩我的示例中的原始图像会产生大约 800KB 的图像。
fetch('https://i.imgur.com/mw7BsYS.jpg')
.then(response => response.blob())
.then(async blob => {
let {
size
} = blob;
console.log("Startingsize", size, 'B');
let img = document.createElement("img");
img.src = URL.createObjectURL(blob);
await new Promise((r) => img.onload = r);
let {
naturalWidth,
naturalHeight
} = img;
console.log(naturalWidth, naturalHeight, size);
const targetByte = 150 * 1024;
// in case first picture is smaller than 150kb
let compressed = { result: blob };
// speeds up large pictures
if (targetByte / size < 0.15) {
naturalWidth *= 0.15;
naturalHeight *= 0.15;
} else if (targetByte / size < 0.25) {
naturalWidth *= 0.25;
naturalHeight *= 0.25;
} else if (targetByte / size < 0.5) {
naturalWidth *= 0.5;
naturalHeight *= 0.5;
} else if (targetByte / size < 0.75) {
naturalWidth *= 0.75;
naturalHeight *= 0.75;
}
// generate thumbnails
while (size > targetByte) {
if (blob.size > targetByte) {
// the bigger the steps, the faster it will be.
naturalWidth *= 0.99;
naturalHeight *= 0.99;
}
let res = await new Promise((resolve, reject) => {
const res = new Compressor(blob, {
maxWidth: naturalWidth,
maxHeight: naturalHeight,
success(blob) {
size = blob.size;
console.log(naturalWidth, naturalHeight, size);
compressed = res;
resolve();
},
error: reject
})
});
}
// replace the compressed with the original image from above
const original = img.src;
img.onclick = () => { if (confirm("sure?")) img.src = original; };
// compressed.result contains the final blob now
img.src = URL.createObjectURL(compressed.result);
await new Promise((r) => img.onload = r);
console.log(compressed.result, img.naturalWidth, img.naturalHeight)
document.body.append(img);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/compressorjs/1.1.1/compressor.js"></script>