前端图片压缩
步骤
Step 1: 绘制图片
💓 将图片绘制到canvas上。
- 👻关键代码:
ctx.drawImage(img, [剪切img的x, 剪切img的y, 剪切img的width, 剪切img的height], 放置img的x, 放置img的y, 放置imgWidth, 放置imgHeight);
-
👉因为透明png转化时透明区域默认显示黑色,所以要给canvas蒙上白色底色先。
-
👉嘿嘿赠送小问题一个。如何用canvas进行瓦片绘制呢?
Step 2: 导出图片
💓 将canvas上的图片数据导出,此时可以自定义导出格式和质量。
-
👻关键代码:
var data = canvas.toDataURL(type, [encoderOption]);
-
👉type默认为image/png。但是如果是png的话图片还是很大,所以还是都压缩成jpg好了喔。
-
👉encoderOption表示图片压缩质量,可选范围0~1,默认0.92
- 👉以上返回(附①)Data URLs。
- 👉【不合作的ios】当图片过大(>=300万像素)时,ios的toDataURL()不会报错,但得到的结果为空。所以我在处理时先限制了图片对应canvas的max-width为手机的显示屏幕宽度,以此来限制图片大小。毕竟手机拍摄的照片一般尺寸巨大。
Step 3: 数据转换
💓 将第二步导出的base64数据转成二进制blob数据。
-
👻关键代码:
-
①
data = dataURL.split(',')[1];
- ②
data = data.replace(/\s/g, '');
- ③
var text = (附②)atob(data);
- ④
var buffer = (附③)new ArrayBuffer(text.length);
-
⑤
var ubuffer = (附④)new Uint8Array(buffer);for (var i = 0; i < text.length; i++) { ubuffer[i] = text.(附⑤)charCodeAt(i);}⑥var blob = new Blob([buffer], {type: type});blob.lastModifiedDate = new Date();
-
👉【不合作的ios】ios下的atob()里不接受空格,所以应先将数据内的空格处理掉,见②。
-
👉【不合作的ios】本来完整版应该再(附⑦)new File一下blob的,毕竟从File对象里来也想压缩完回到File对象里去。可惜ios不怎么支持File()函数。在ios 10.8系统下new File([blob], “name.JPG”, {type:”image/jpeg”})不会报错,但得到的file对象有莫名bug 叹气
- 安卓机下:
- ios下:
如上图 虽然ios上传file时也可以读到file的size和name等信息 但对应value为空。
所以只可以直接传blob。其实我个人觉得file就只是加上名字和创建日期和type的blob拉…毕竟都是二进制文件而已。
Step 4: 上传图片
💓 完工大吉!
- 👻关键代码:
formdata.append('img', blob, 'name.jpg');
附录
- 定义:URLS prefixed with ‘data:’
- 格式:’data: [] [; 编码方式], ‘
- 例子: ‘data:image/jpeg; base64, data’
- 所以DataURL.split(‘,’)[1]可以拿到对应文件数据。
②window.atob():解码base64编码的数据
③new ArrayBuffer(length):代表固定长度的二进制数据
④Unit8Array: represents an array of 8-bit unsigned integers
⑤String.charCodeAt():返回指定字符对应的utf-16 code
⑦file = new File([blob], “name.JPG”, {type:”image/jpeg”})
⑧用canvas进行一大张图片img瓦片绘制的答案:
假设有一张img就是很无聊。它希望自己的x轴被分为nx部分,y轴被分为ny部分,被打碎以后再拼到canvas上去…
var nw = img.width/nx, nh = img.height/ny; for(var i = 0; i < nx; i++) { for(var j = 0; j < ny; i++) { ctx.drawImage(img, nw*i, nh*j, nw*h, nh*j, nw, nh) }}
最后前端压缩图片…真的真的超级超级漫长的!!会容易给人这个网页烂掉了的错觉…所以应该尽量还是避免这样子的操作把恩🤦🤦🤦
一如既往的小demo
Refs
移动前端—图片压缩上传实践 By W.Axes