我是一名服务器端开发人员,从纯 JS 开始学习客户端操作的技巧。
目前我正在使用纯 JS 来调整通过浏览器上传的图像的尺寸。
我遇到了这样一种情况:将 1018 x 1529.jpg
文件缩小到 400 x 601.jpeg
会产生更大尺寸(以字节为单位)的文件。它从70013
字节到74823
字节。
我的期望是应该缩小规模,而不是通胀。这是怎么回事,有没有办法修补这种情况?
注意:让我特别困惑的一点是,每个图像的压缩开始时都没有任何目标先前压缩的先验知识。因此,任何低于 100 的质量级别都会进一步降低图像质量。因此,这应该始终减小文件大小。但奇怪的是,这并没有发生?
如果需要,我的相关 JS 代码是:
var max_img_width = 400;
var wranges = [max_img_width, Math.round(0.8*max_img_width), Math.round(0.6*max_img_width),Math.round(0.4*max_img_width),Math.round(0.2*max_img_width)];
function prep_image(img_src, text, img_name, target_action, callback) {
var img = document.createElement('img');
var fr = new FileReader();
fr.onload = function(){
var dataURL = fr.result;
img.onload = function() {
img_width = this.width;
img_height = this.height;
img_to_send = resize_and_compress(this, img_width, img_height, "image/jpeg");
callback(text, img_name, target_action, img_to_send);
}
img.src = dataURL;
};
fr.readAsDataURL(img_src);
}
function resize_and_compress(source_img, img_width, img_height, mime_type){
var new_width;
switch (true) {
case img_width < wranges[4]:
new_width = wranges[4];
break;
case img_width < wranges[3]:
new_width = wranges[4];
break;
case img_width < wranges[2]:
new_width = wranges[3];
break;
case img_width < wranges[1]:
new_width = wranges[2];
break;
case img_width < wranges[0]:
new_width = wranges[1];
break;
default:
new_width = wranges[0];
break;
}
var wpercent = (new_width/img_width);
var new_height = Math.round(img_height*wpercent);
var canvas = document.createElement('canvas');//supported
canvas.width = new_width;
canvas.height = new_height;
var ctx = canvas.getContext("2d");
ctx.drawImage(source_img, 0, 0, new_width, new_height);
return dataURItoBlob(canvas.toDataURL(mime_type),mime_type);
}
// converting image data uri to a blob object
function dataURItoBlob(dataURI,mime_type) {
var byteString = atob(dataURI.split(',')[1]);
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);//supported
for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); }
return new Blob([ab], { type: mime_type });
}
如果有必要,这是我使用的测试图像:
这是图像的原始位置。
请注意,对于我尝试的其他几个图像,代码确实按预期运行。它并不总是搞砸结果,但现在我不能确定它总是有效。对于这个问题的范围,让我们坚持使用纯 JS 解决方案。