前端女程序媛,手把手教你,如何编写一个前端图片的各种效果

前言

今天我们要讲解下如何编写一个图片压缩、方向纠正插件,附带着会讲解下如何上传和预览。

为什么重点放在图片压缩和方向纠正?

相信大家在做项目过程中,经常会遇到上传图片到后端,但是由于图片过大,需要对图片压缩处理。特别在移动端,手机拍的照片普遍过于大了,我们有时候只是需要上传一张头像,很小就够用了。还有在部分手机上(已知苹果手机)拍的照片存在方向角度问题,这时就需要我们来纠正图片角度了。

很多同学多数时候是在用别人写好的图片压缩上传插件。针对我们的需求,这些插件有时候不能达到我们最理想的效果,自己写呢,又不会写,很是头疼。今天就深入剖析讲解下,教会大家编写自己的图片压缩、方向纠正插件,以及预览和上传压缩后图片数据。

实现原理

压缩图片并且上传主要用到filereader、canvas 以及 formdata 这三个h5的api和插件EXIF.js。逻辑并不难。整个过程就是:

(1)用户使用input file上传图片的时候,用filereader读取用户上传的图片数据(base64格式)

(2)把图片数据传入img对象,然后将img绘制到canvas上,用EXIF.js对图片方向进行纠正,再调用canvas.toDataURL对图片进行压缩,获取到压缩后的base64格式图片数据,转成二进制

(3)获取到压缩后的图片二进制数据,预览。

(4)将压缩后的图片二进制数据塞入formdata,再通过XmlHttpRequest提交formdata

如此四步,就完成了图片的压缩、方向纠正、预览和上传。

插件设计思考

考虑到在实际项目中,可能用不同的开发框架(vue.js/JQ/react.js/angular.js/anu.js等),图片预览的UI样式也可能不同,图片数据上传方法可能不同。因为图片压缩和方向纠正这两块的逻辑多变性比较低,我们这里把图片压缩和方向纠正抽离出来,封装为一个插件库。

【一】获取图片数据

先是获取图片数据,也就是监听input file的change事件,然后获取到用来压缩上传的文件对象files,将files传到【图片压缩、方向纠正插件】中进行处理。

这时候根据每个人的需求,也可以预览未压缩的图片。


【二】图片压缩、方向纠正插件实现

上面做完图片数据的获取后,就可以做process压缩图片的方法了。而压缩图片也并不是直接把图片绘制到canvas再调用一下toDataURL就行的。

在IOS中,canvas绘制图片是有两个限制的:

首先是图片的大小,如果图片的大小超过两百万像素,图片也是无法绘制到canvas上的,调用drawImage的时候不会报错,但是你用toDataURL获取图片数据的时候获取到的是空的图片数据。

再者就是canvas的大小有限制,如果canvas的大小大于大概五百万像素(即宽高乘积)的时候,不仅图片画不出来,其他什么东西也都是画不出来的。

应对上面两种限制,我把图片宽度、高度压缩控制在1000px以内,这样图片最大就不超过两百万像素了。在前端开发中,1000px*1000px基本可以满足绝大部分的需求了。当然了还有更完美的瓦片式绘制的方法,我们这里就说瓦片式绘制方法了。

如此一来就解决了IOS上的两种限制了。

除了上面所述的限制,还有两个坑,一个就是canvas的toDataURL是只能压缩jpg的(

这句话的详细解释可以看下面的Tip讲解

),当用户上传的图片是png的话,就需要转成jpg,也就是统一用canvas.toDataURL('image/jpeg', 0.5) , 类型统一设成jpeg,而压缩比就自己控制了。

另一个就是如果是png转jpg,绘制到canvas上的时候,canvas存在透明区域的话,当转成jpg的时候透明区域会变成黑色,因为canvas的透明像素默认为rgba(0,0,0,0),所以转成jpg就变成rgba(0,0,0,1)了,也就是透明背景会变成了黑色。解决办法就是绘制之前在canvas上铺一层白色的底色。

在压缩图片之前,我们判断图片角度,如果图片角度不正确,还需要用EXIF.js把图片角度纠正过来。

压缩完图片,把base64的图片数据转成二进制数据存储到暂存区中,等待被getBlobList获取使用。

Tip:canvas的toDataURL是只能压缩jpg

这句话我可能说的不清楚,我想表达的意思是这个api无论是jpeg还是png,最后导出的时候,都跟jpeg没啥差别了。因为png图片的透明性质在canvas中是无效的,会被canvas添加默认的黑色背景,我在文中讲解的时候,用白色背景处理了,所以最后导出的图片,无论你设置的是png还是jpeg都跟jpeg没啥区别了,因为无法保持png的透明度性质了


​【三】获取压缩后的图片二进制数据,预览图片

完成图片压缩后,就可以获取压缩后的图片二进制数据了,把获取到的图片二进制数据存起来;获取到数据后,可以拿来预览。

由于实际项目中,每个项目的UI样式设计可能不一样,开发者可以根据自己的UI样式来预览图片。


【四】提交图片数据到后台

new一个formdata对象,将上一步获取到的 blobFileList 图片二进制数据 append 到 formdata中,用任意你喜欢的ajax库进行上传。当然也可以用原生ajax上传。

对想学习前端的小伙伴,小编给你们准备了全套前端电子版书籍,包含了目前大部分前端开发的书

【【前端学习交流裙 330336289.进裙邀请码(编号):寂静 。裙内不定时分享干货,包括2018最新的企业案例学习资料和零基础入门教程,欢迎自学的小白和大神】

结语

喜欢这篇文章的话,请关注我,我会持续更新技术文章到我的主页。谢谢支持~

推荐阅读更多精彩内容