前言说到图片压缩,很多你想到或者经常用到的工具都可以实现。比如客户端类有图片压缩工具PPDuck3,JS实现类有插件compression.js,或者OSS上传在线处理。文件上传后,访问文件时还有图片压缩配置选项。但是,能不能用一套JS实现的图片压缩代码?当然,还是先说说吧。压缩的思想涉及到JS中的图片压缩。我的想法是利用Canvas的绘图能力,通过调整图片的分辨率或者绘图质量来达到图片压缩的效果。思路如下:获取上传的Input中的图片对象文件,将图片转成base64格式。base64编码的图像由Canvas转换和压缩。这里会用到Canvas的drawImage和toDataURL接口。一是调整图像的分辨率,二是调整图像压缩质量和输出。后续会有详细介绍转换后的图像生成对应的新图像,然后输出优劣势。不过Canvas压缩方式也有其优缺点:优点:实现简单、可配置参数、自定义图片大小、指定区域裁剪等。缺点:只有jpeg和webp支持在原始图片尺寸下调整图片质量,达到压缩图片的效果。其他图片格式只能通过调整代码大小来实现普通下载上面的代码可以直接拿来看效果,不喜要使用ForVue,还可以稍微调整一下代码。下面开始分解代码的实现思路。Input上传File处理,通过FileReader的readAsDataURL方法将File对象转换为URL格式(base64编码)的字符串。constfileObj=document.querySelector('#input-img').files[0];letreader=newFileReader();//读取文件reader.readAsDataURL(fileObj);Canvas处理File对象创建Image对象,画布canvas,并设置好你要下载的图片大小,调用drawImage方法在canvas中绘制上传的图片letimage=newImage();//新建一个img标签image.src=e.target.result;letcanvas=document.createElement('canvas');letcontext=canvas.getContext('2d');context.drawImage(image,0,0);Api分析:drawImagecontext.drawImage(img,sx,sy,sWidth,sHeight,dx,dy,dWidth,dHeight);img为图片对象,可以是页面上获取的DOM对象,也可以是虚拟DOM中的图片对象dx,dy,dWidth,dHeight表示在canvas上规划一块区域放置图片,dx,dy是Canvas元素上绘图位置的X轴和Y轴坐标,dWidth,dHeight是指画布的宽度在Canvas元素上绘制的图片和高度(如果不指定,绘制时图片的宽高不缩放)。sx、sy、width、sheight4个参数用于对源图像进行裁剪,表示图像在画布上显示的大小和位置。sx,sy分别代表裁剪位置在源图上的X轴和Y轴坐标,然后选择宽高维度的区域范围,裁剪后的图像就是最终显示在Canvas上的图像内容(width,sheight未指定情况下,整个矩形(裁剪)从坐标sx和sy开始,到图片右下角结束)。下面是一个图像绘制的例子:context.drawImage(image,0,0,100,100);context.drawImage(image,300,300,200,200);context.drawImage(image,0,100,150,150,300,0,150,150);Api中比较奇怪的是sx,sy,width,height是可选参数,但是位置在dx,dy,dWidth,dHeight之前。Canvas输出图片调用canvas的toDataURL方法输出base64格式的图片。canvas.toDataURL(`image/${type}`);Api解析:toDataURLcanvas.toDataURL(type,encoderOptions);type可选图片格式,默认为image/png。encoderOptions是可选的。当指定的图片格式为image/jpeg或image/webp时,图片的质量可以从0到1中选择。如果超出取值范围,将使用默认值0.92。其他参数被忽略。a标签的下载调用标签的download属性完成图片的下载。api分析:download//href下载必填downloadfilename可选,指定作为文件名使用的文本。href文件的下载地址。非主流浏览器的下载处理可以解决Chroma、Firefox、Safari(自测支持)浏览器的下载功能,因为IE等浏览器不支持下载属性,所以需要其他下载方式,所以有一个code后续内容//base64图片转blob下载downloadImg(){letparts=this.compressImg.split(';base64,');letcontentType=parts[0].split(':')[1];letraw=窗口.atob(部分[1]);letrawrawLength=raw.length;letuInt8Array=newUint8Array(rawLength);for(leti=0;i标签的download属性来下载Api分析:atobbase-64解码的方法需要atob()window.atob(encodedStr)encodedStr,是btoa()方法编码的字符串,btoa()是使用base64编码的方法。Api分析:Uint8ArraynewUint8Array(length)length创建一个无符号整数数组,初始化为0,包含length元素。Api分析:BlobBlob对象代表一个不可变的、原始数据文件类对象。//ConstructorallowstocreateBlobobjectsfromotherobjectsnewBlob([obj],{type:createType})objstringcontentcreateType要构造的类型兼容性IE10以上Api分析:createObjectURL静态方法会创建一个DOMString。objectURL=URL.createObjectURL(object);object用于创建URL的File对象、Blob对象或MediaSource对象。api分析:window.navigator//不推荐官方文件下载方式,只针对IE和兼容10以上//msSaveBlob只提供下载//msSaveOrOpenBlob支持下载打开window.navigator.msSaveOrOpenBlob(blob,fileName);blob要下载的blob对象文件名下载后命名的文件的名称。小结本文仅介绍图像压缩的一些思路。简单的使用场景可以介绍如下。当然还会扩展更多的使用场景,有待大家一起去探索。图片上传存储如需对文件大小和格式有要求,可对图片进行统一压缩处理温馨提示:由于部分界面存在IE兼容问题,IE浏览器仅支持IE10及以上版本下载.