当前位置: 首页 > Web前端 > HTML5

H5在客户端使用javascript对图片进行压缩缩放,附上ts代码

时间:2023-04-05 16:43:57 HTML5

有时候我们有这样的需求,需要对前端选中的图片进行压缩。这种治疗的原因可能是。减少带宽使用并提高效率。裁剪图片以满足上传要求。(现在手机摄像头分辨率很高,直接用比较大)前端压缩图片主要用到的API有:CanvasImageFileBlobFileReader,如图,设置三个方法为ImagetoCanvastoFile/**main方法*/异步函数miniImage(params:{url?:string,file?:File,quality?:number,fileName?:string,size?:{width:number,height:number},fitLength?:number}={quality:1,fileName:'压缩图片'}){console.assert(params.url||params.file,'url和file必须是一个')console.assert(params.quality<=1&¶ms.quality>0,'质量范围是0-1')constimg=awaittoImage({file:params.file,url:params.url})constcanvas=toCanvas({img,size:params.size,fitLength:params.fitLength})returnawaittoFile(canvas,{quality:params.quality,fileName:params.fileName})}toImage方法该方法主要使用Image、File、FileReader进行转换,如果参数是file,则使用后者,如果只是url,直接使用图片。其中要注意FilerReader的用法,在h5的开发中很多地方都会用到。/**转换为图像*/asyncfunctiontoImage(params:{file?:File,url?:string}):Promise{returnnewPromise((reso,rej)=>{const{file,url}=paramsconstimg=newImage()img.onload=()=>{returnreso(img)}//文件方法if(file){constreader=newFileReader()reader.onload=(e)=>{img.setAttribute('src',e.target?.resultasstring)}reader.readAsDataURL(file)}elseif(url){img.setAttribute('src',url)}else{console.error(`parseImageerror`)}})}toCanvas方法该方法主要用到CanvasRenderingContext2D的drawImage方法。该方法的入参定义:drawImage(HTMLImageElement,dx,dy,dw,dh)为传入方法,然后绘制图片,控制绘制位置,以及绘制的宽高。此外,我们还需要做更多的兼容性,增加输入参数,控制图片的大小。代码如下所示。/**转换为画布*/functiontoCanvas(img:HTMLImageElement,options?:{size?:{width:number,height:number},maxLength?:number}){constcanvas=document.createElement('canvas')让{size,maxLength}=options??{}let{height,width}=imgif(size||maxLength){if((!size?.height||!size.width)&&!maxLength)maxLength=size?.height??size?.width//设置长度并调整if(maxLength){letmaxlen=Math.max(height,width)letrate=maxLength/maxlenheight=maxlen===height?maxLength:height*ratewidth=maxlen===width?maxLength:width*rate}elseif(size){//设置大小height=size.heightwidth=size.width}}canvas.height=heightcanvas.width=widthconstctv=canvas.getContext('2d')ctv?.drawImage(img,0,0,width,height)returncanvas}toFile方法的最后一步是将图片转换成我们需要上传的文件。这一步主要是使用canvas的toBlob方法,然后通过File生成一个新的文件。注意:在js中,一个文件基本就是Blob加name。具体代码如下:/**canvastofile*/functioncanvasToFile(canvas:HTMLCanvasElement,options:{fileName?:string,quality?:number}={quality:1,fileName:'picture'}):Promise{returnnewPromise((reso,rej)=>{canvas.toBlob((blob)=>{constfile=newFile([blobasBlob],options!.fileNameasstring,{type:'image/png',})reso(file)},'',options.quality)})}miniImageByUrl方法最后,我们结合上面写了一个预览的方法,将生成的canvas直接转换成dataUrl,显示在页。/**处理图像压缩并将其转换为url*/exportconstimageMinByUrl=async(params:{file?:Fileurl?:stringquality?:numbermaxLength?:number,size?:{height:number,width:number},}={quality:1})=>{console.assert(params.file||params.url,'必须有文件或url输入参数')constimg=awaittoImage({file:params.file,url:params.url})constcanvas=toCanvas(img,{size:params.size,maxLength:params.maxLength})returncanvas.toDataURL('image/png',params.quality)}npm可以通过cdd-lib为了直接使用,该库提供了imageMinByUrl和imageMin方法。参考:<<如何在Javascript中调整图片大小?>>