背景作为一名前端工作者,相信大家在开发系统的时候,经常会遇到这样的需求,即需要为用户保存上传的图片。很多菜鸟遇到这个问题的时候,都会被吓一跳,我认为这将是一个棘手的问题。当你读完这篇文章时,你会发现你是盲目地做的。事实就是这么简单。进入正题:图片文件上传现在很多项目都实现了在系统中保存图片,大部分只是在系统数据库中保存对应图片的url,而实际的图片资源会放在图片服务器上比如阿里.当然,有些项目会选择将图片base64格式的字符串保存在自己的数据库中,如下通过一个Vue实例来说明这两种方式的一些具体实现:首先,我们需要从用户那里获取图片资源。这时候我们需要用到HTML的标签,type值为file,指定input标签为文件类型的表单输入,其accept属性设置为“image/*”,指定仅接受图像资源的文件;标签的src属性中,这样也可以达到渲染图片的目的,所以有人选择保存这种格式的图片;但这不是主流方式,也会导致我们的数据库过于冗余;压缩(事件){varfile=event.target.files;varreader=newFileReader(),imgFile=file[0];如果(imgFile.type.indexOf('image')==0){reader.readAsDataURL(imgFile);}else{this.$Message.infor('文件类型仅为图片')}letimg=new图像();reader.onload=function(e){img.src=e.target.result;};}图片压缩,我们主要使用canvas来实现这个功能,通过canvas.getContext('2d')。drawImage()方法重绘图片,使用canvas.toDataURL(type,encoderOptions)方法返回一个包含图片显示的dataURI,type为图片格式,encoderOptions为图片的分辨率,从0递增到1.这个压缩过程不难理解,思路就是获取图片的高和宽,计算出它的像素大小,和自己设定的一个极限值比较,看看我们的尺寸是否需要压缩。例如,示例中的比率表示图片宽高的压缩比。我们可以在不改变宽高的情况下修改图片的文件大小,通过drawImage(image,sx,sy,sWidth,sHeight,dx,dy,dWidth,dHeight)重绘图片,可以传入九个参数,代表绘制到上下文的元素,源图像选择矩形左上角的X坐标,源图像选择矩形左上角的Y坐标,源图像选择矩形的宽度图像,源图像的选择矩形的高度,目标画布的左上角在目标画布的X轴位置,目标画布的左上角在目标画布的X轴位置目标画布上的Y轴,目标画布上绘制的图像的宽度,目标画布上绘制的图像的高度;整个函数实现如下:compress(event){varfile=event.target.files;varreader=newFileReader(),imgFile=file[0];如果(imgFile.type.indexOf('image')==0){reader.readAsDataURL(imgFile);}else{this.$Message.infor('文件类型仅为图片')}letimg=newImage();reader.onload=函数(e){img.src=e.target.result;};varimgP=newPromise((resolve,reject)=>{img.onload=()=>{varcanvas=document.createElement("canvas");varctx=canvas.getContext('2d');//tile画布vartCanvas=document.createElement("canvas");vartctx=tCanvas.getContext("2d");varinitSize=img.src.length;varwidth=img.width;varheight=img.height;//图像像素大于400万像素,计算压缩到小于400万varratio;if((ratio=width*height/4000000)>1){ratio=Math.sqrt(ratio);width/=ratio;height/=ratio;}else{ratio=1;}canvas.width=width;canvas.height=height;ctx.fillStyle="#fff";ctx.fillRect(0,0,canvas.width,canvas.height);//如果图片太大,使用tile来绘制变量计数;if((count=width*height/1000000>1)){count=~~(Math.sqrt(count)+1);//计算瓦片数量varnw=~~(width/count);varnh=~~(高度/计数);tCanvas.width=nw;tCanvas.height=nh;for(vari=0;i
