Javascript 调整画布质量以达到预定的图像文件大小

Javascript 调整画布质量以达到预定的图像文件大小,javascript,html,canvas,Javascript,Html,Canvas,我想使用画布调整图像的大小(如超过限制时减小文件大小)。我看到在画布上绘制的结果图像大小保持宽度和高度不变,根据在画布上绘制的内容产生不同的文件大小 如果获得所需的文件大小,我愿意进一步降低分辨率 如何确保文件(图像)大小的分辨率在限制范围内 指 var el=document.getElementById('f'); el.addEventListener(“变更”,一旦变更); 函数onChange(e){ var file=this.files[0]; 控制台日志(“更改”); var

我想使用画布调整图像的大小(如超过限制时减小文件大小)。我看到在画布上绘制的结果图像大小保持宽度和高度不变,根据在画布上绘制的内容产生不同的文件大小

如果获得所需的文件大小,我愿意进一步降低分辨率

如何确保文件(图像)大小的分辨率在限制范围内

var el=document.getElementById('f');
el.addEventListener(“变更”,一旦变更);
函数onChange(e){
var file=this.files[0];
控制台日志(“更改”);
var fr=new FileReader();
fr.onload=功能(e){
drawOnCanvas(即目标、结果);
}
fr.readAsDataURL(文件);
}
函数drawOnCanvas(imgSrc){
var canv=document.createElement('canvas'),
img=新图像();
控制台日志(“图纸”);
canv.宽度=canv.高度=500;
ctx=canv.getContext('2d');
img.onload=函数(){
console.log(“图像加载”);
ctx.drawImage(img,0,0,img.width,img.height,0,0,canv.width,canv.height);
试一试{
document.body.removeChild(document.querySelector('canvas');
}捕获(e){}
文件.正文.附件(canv);
blob=canvasToFile(canv.toDataURL());
警报(“文件大小”+blob.SIZE);
}
img.src=imgSrc;
}
函数canvasToFile(dataUrl){
var encData=dataUrl.split(',')[1],
binString=atob(encData),
binData=新的UINT8数组(binString.length),
i、 斑点;
对于(i=0;i
尝试上载不同的图像文件,并查看相同输出分辨率的大小差异:


您遇到的是,默认的
类型
参数是
图像/png
,而且它实际上是图像数据的base64编码

  • 对于前者,大多数浏览器都支持
    image/jpeg
    作为图像类型。由于jpg压缩,这可能会减少数据大小,但这首先会启用方法的
    encoderOptions
    参数,该参数可以转换为质量参数,并且需要0到1的浮点。
    请注意,如果转换为jpg,您无法确定数据是否会更亮:如果图像主要由透明像素组成,则png将更亮。此外,请记住jpeg压缩会降低图像质量,请参阅最后一个片段以查看0的结果:)

  • 对于后者(您可以找到原因的解释),解决方案是将dataURL转换回blob

下面是一个片段来演示:

var input=document.querySelector('input');
var canvas=document.createElement('canvas'),
ctx=canvas.getContext('2d');
函数绘图(){
var img=新图像();
img.src=URL.createObjectURL(this.files[0]);
img.onload=函数(){
canvas.width=this.naturalWidth;
canvas.height=this.naturalHeight;
ctx.drawImage(这个,0,0);
var noData=canvas.toDataURL();
png_data.innerHTML='dataURL长度:'+noData.length;
var noBlob=dataURItoBlob(noData);
png_blob.innerHTML='blob size:'+noBlob.size;
var jpgData10=canvas.toDataURL('image/jpeg',1),
jpgData5=canvas.toDataURL('image/jpeg',0.5),
jpgData0=canvas.toDataURL('image/jpeg',0);
jpg_data.innerHTML='quality=1:'+jpgData10.length+'
'; jpg_data.innerHTML+='quality=0.5:'+jpgData5.length+'
'; jpg_data.innerHTML+='quality=0:'+jpgData0.length+'
'; var jpgBlob10=dataURItoBlob(jpgData10); jpg_blob.innerHTML='blob quality=1:'+jpgBlob10.size+'
'; var jpgBlob5=dataURItoBlob(jpgData5); jpg_blob.innerHTML+='blob quality=.5:'+jpgBlob5.size+'
'; var jpgBlob0=dataURItoBlob(jpgData0); jpg_blob.innerHTML+='blob quality=0:'+jpgBlob0.size; } this.previousElementSibling.innerHTML='原始大小:'+this.files[0].size; } input.onchange=绘图; //取自https://stackoverflow.com/a/5100158/3702797 函数dataURItoBlob(dataURI){ var-byteString; if(dataURI.split(',')[0].indexOf('base64')>=0) byteString=atob(dataURI.split(',)[1]); 其他的 byteString=unescape(dataURI.split(',)[1]); var mimeString=dataURI.split(',')[0]。split(':')[1]。split(';')[0]; var ia=新的Uint8Array(byteString.length); for(var i=0;i


巴布亚新几内亚:
Jpeg:
您遇到的是,默认的
类型
参数是
图像/png
,而且它实际上是图像数据的base64编码

  • 对于前者,大多数浏览器都支持
    image/jpeg
    作为图像类型。由于jpg压缩,这可能会减少数据大小,但这首先会启用方法的
    encoderOptions
    参数,该参数可以转换为质量参数,并且需要0到1的浮点。
    请注意,如果转换为jpg,您无法确定数据是否会更亮:如果图像主要由透明像素组成,则png将更亮。此外,请记住jpeg压缩会降低图像质量,请参阅最后一个片段以查看0的结果:)

  • 对于后者(您可以找到原因的解释),解决方案是将dataURL转换回blob

下面是一个片段来演示:

var input=document.querySelector('input');
var canvas=document.createElement('canvas'),
ctx=canvas.getContext('2d');
函数绘图(){
var img=新图像();
img.src