提问人:SA__ 提问时间:12/5/2021 更新时间:9/6/2022 访问量:169
如何在compressjs中动态查找质量参数
How to find quality parameter in compressjs dynamically
问:
我的文件大小是 500kb(它会动态出现任何大小)。我的目标是 150kb。
由于某些原因,我只能选择质量
new Compressor(selectedFile1, {
quality: targetRatio,
即,如果我将 targetRatio 传递给 0.7,它会将图像减少到 159kb~
为了动态地找到targetRatio,我所做的是
var targetRatio = fileSize / 150;
但是,我无法弄清楚如何找到 targetRatio 以获得确切的值,即减少到 150kb
答:
2赞
Christopher
12/5/2021
#1
达到 150kb 修改质量,并不适用于每个图像。
JPEG 压缩量通常以质量级别的百分比来衡量。100% 质量的图像(几乎)没有损失,而 1% 质量的图像质量非常低。一般来说,90%或更高的质量水平被认为是“高质量”,80%-90%是“中等质量”,70%-80%是低质量。
如果您使用 15.594 x 3.936 jpg(示例),根据存储的信息,其大小可能为 ~2.5mb,则 jpg 格式将无法达到 150kb。
因此,以 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>
0赞
Noob and Nerd
9/6/2022
#2
要精确地达到一个尺寸几乎是不可能的。因素太多了。你可以粗略地用三分法则来确定它,或者从克里斯托夫那里获取信息。我会提前减小图像尺寸,您应该始终考虑质量。否则可以使用 .gif,但这仅支持 256 种颜色,但会更小。
上一个:在jquery中进行数学运算
评论