在做 H5 开发时,难免会遇到有需要上传图片的需求。这种需要我们去引入一些库,或者自己来实现这么个功能。那么一般是如何去处理压缩图片的需求呢?这里简要的概述一下实现原理~
目前主流对图片进行处理都是使用canvas
技术~当我们碰到需要压缩图片的场景时,第一种我们就可以尝试控制图片的尺寸。因为图片的尺寸越大,里面包含的信息就越多,自然体积也随着增加了起来。
我们可以做一个宽高的限制,超出就对其进行尺寸的缩放。那么限制最大值是多少呢?这个应该根据产品或者需求来调整。当然,裁剪图片也是一种思路,那么该如何去裁剪,让用户选择还是我们自定义?这也是需要考虑的一点。
判断缩放的方法主要使用drawImage
将图片导入canvas,如果图片超过了指定的宽高,就进行缩放图片。关于这一点,我觉得张鑫旭老师的这篇文章讲的已经足够简洁的了,感兴趣的同学可以看这边~
第二种就是使用canvas
提供的另一个接口:canvas.toDataURL(type, encoderOptions)
。这是浏览器原生提供可以压缩图片的方法,该方法返回一个包含图片展示的data URI
(也就是我们常说的base64)。
它接受两个可选参数,我们可以使用type
参数指定其类型,默认为PNG
格式。encoderOptions
则是压缩图片质量参数,区间在 0~1 之间。值得注意的是,压缩图片质量这个参数只对image/jpeg
或image/webp
有效。所幸的是,其他格式用不了压缩图片的参数,但浏览器还是会对图片进行压缩处理,剔除对 web 展示没啥用的元数据(虽然可能会涉及到版权纠纷的问题)。
1 | var canvas = document.getElementById("canvas"); |
但单单是转为 base64 是不能满足我们一些需求的,这时我们可能会想要让它再转为对服务端友好的blob
类型。
这时我们就需要用到window.atob()
, 将已经编译成 base64 的字符串解码为二进制。
1 | var type = fullQuality.split(',')[0].split(':')[1].split(';')[0]; |
如果是想转为File
类型的话,和上面的方法实现的也一致..
1 | // https://developer.mozilla.org/en-US/docs/Web/API/File/File |
哇,转个类型都看起来好像挺麻烦的样子呢…那么有没有内置的方法呀?答案是有,canvas 里有个toBlob(callback, type, encoderOptions)
的方法, 它接受三个参数,一个是将canvas转为blob
后接受的回调函数、一个是指定的图片格式、另一个是图片质量,区间也在 0~1 之间。
看起来这个方法似乎比上面那个更好用呢..然而残念的是,这货还受着兼容性影响,不在乎的兼容性的话倒是可以使用… 不然就需要上一种polyfill 的方式来实现~
1 | canvas.toBlob(function (blob) { |