前端压缩图片代码,支持移动端和pc 端,还有拍照后获取到的照片
Posted blackbentel
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端压缩图片代码,支持移动端和pc 端,还有拍照后获取到的照片相关的知识,希望对你有一定的参考价值。
1. upload 使用者调用的方法
2. rotateImg 旋转照片,用于把ios拍照后获取到的图片摆正
3. dataURLtoFile 将压缩后的图片转为file 对象,区分一个 blob 和 base64, 兼容哪个就用哪个
4. 得先引入 exif-js 用于拿到图片信息,确定 iOS 怎么旋转的
1 import EXIF from ‘exif-js‘ 2 var picValue = null, 3 headerImage = ‘‘, 4 imgName = ‘‘, 5 imgType = ‘‘ 6 const MAXSIZE = 1024 7 8 function upload(e, cb) { // 入参 1. file change事件中的事件对象, 2. 回调函数 9 var files = e.target.files || e.dataTransfer.files; 10 if (!files.length) return; 11 picValue = files[0]; 12 imgName = picValue.name 13 imgType = picValue.type.split(‘/‘)[1] 14 return imgPreview(picValue, cb); 15 } 16 17 function rotateImg(img, rotateDegree, canvas) { 18 //最小与最大旋转方向,图片旋转4次后回到原方向 19 if (img == null) return; 20 //img的高度和宽度不能在img元素隐藏后获取,否则会出错 21 let height = img.height; 22 let width = img.width; 23 //旋转角度以弧度值为参数 24 let degree = rotateDegree * Math.PI / 180; 25 let ctx = canvas.getContext(‘2d‘); 26 switch (rotateDegree) { 27 case 0: 28 canvas.width = width; 29 canvas.height = height; 30 ctx.drawImage(img, 0, 0); 31 break; 32 case 90: 33 canvas.width = height; 34 canvas.height = width; 35 ctx.rotate(degree); 36 ctx.drawImage(img, 0, -height); 37 break; 38 case 180: 39 canvas.width = width; 40 canvas.height = height; 41 ctx.rotate(degree); 42 ctx.drawImage(img, -width, -height); 43 break; 44 case 270: 45 canvas.width = height; 46 canvas.height = width; 47 ctx.rotate(degree); 48 ctx.drawImage(img, -width, 0); 49 break; 50 } 51 } 52 53 function compress(img, Orientation, cb) { 54 let obj = {} 55 let that = img 56 Orientation = Orientation ? Orientation : ‘‘ 57 // obj.width = that.width > 750 ? 750 : that.width 58 // 默认按比例压缩 59 let w = that.width, 60 h = that.height, 61 scale = w / h; 62 w = obj.width || w; 63 h = obj.height || (w / scale); 64 let quality = .7; // 默认图片质量为0.7 65 //生成canvas 66 let canvas = document.createElement(‘canvas‘); 67 let ctx = canvas.getContext(‘2d‘); 68 ctx.fillStyle = ‘rgba(255, 255, 255, 0)‘; 69 // 创建属性节点 70 let anw = document.createAttribute("width"); 71 anw.nodeValue = w; 72 let anh = document.createAttribute("height"); 73 anh.nodeValue = h; 74 canvas.setAttributeNode(anw); 75 canvas.setAttributeNode(anh); 76 ctx.drawImage(that, 0, 0, w, h); 77 // 图像质量 78 if (obj.quality && obj.quality <= 1 && obj.quality > 0) { 79 quality = obj.quality; 80 } 81 if (Orientation && Orientation != 1) { 82 switch (Orientation) { 83 case 6: //需要顺时针(向左)90度旋转 84 rotateImg(that, 90, canvas); 85 break; 86 case 8: //需要逆时针(向右)90度旋转 87 rotateImg(that, 270, canvas); 88 break; 89 case 3: //需要180度旋转 90 rotateImg(that, 180, canvas); //转两次 91 break; 92 } 93 } 94 //进行最小压缩 95 let ndata = canvas.toDataURL(‘image/jpeg‘, quality); 96 97 if (ndata.length > MAXSIZE) { 98 console.log(ndata.length); 99 let img2 = new Image(); 100 img2.src = ndata; 101 img2.onload = function () { 102 compress(img2, ‘‘, cb) 103 } 104 } else { 105 headerImage = ndata; 106 try { 107 cb(dataURLtoFile(headerImage, imgName), { 108 headerImage, 109 imgName 110 }) 111 } catch (error) { 112 console.error(error.message); 113 } 114 } 115 } 116 117 function dataURLtoFile(dataurl, filename) { //转换为file对象 118 try { 119 let arr = dataurl.split(‘,‘), 120 mime = arr[0].match(/:(.*?);/)[1], 121 bstr = atob(arr[1]), 122 n = bstr.length, 123 u8arr = new Uint8Array(n); 124 while (n--) { 125 u8arr[n] = bstr.charCodeAt(n); 126 } 127 let blob = new Blob([u8arr], { 128 type: mime 129 }); 130 return blob 131 } catch (error) { 132 try { 133 let arr = dataurl.split(‘,‘), 134 mime = arr[0].match(/:(.*?);/)[1], 135 bstr = atob(arr[1]), 136 n = bstr.length, 137 u8arr = new Uint8Array(n); 138 while (n--) { 139 u8arr[n] = bstr.charCodeAt(n); 140 } 141 let file = new File([u8arr], filename, { 142 type: mime 143 }); 144 return file 145 } catch (error) { 146 console.error(error); 147 alert(‘您的手机不支持上传图片‘) 148 } 149 } 150 } 151 152 function imgPreview(file, cb) { 153 // let self = this; 154 let Orientation; 155 //去获取拍照时的信息,解决拍出来的照片旋转问题 156 EXIF.getData(file, function () { 157 Orientation = EXIF.getTag(this, ‘Orientation‘); 158 // alert(Orientation) 159 }); 160 // 看支持不支持FileReader 161 if (!file || !window.FileReader) return; 162 163 if (/^image/.test(file.type)) { 164 // 创建一个reader 165 let reader = new FileReader(); 166 // 将图片2将转成 base64 格式 167 reader.readAsDataURL(file); 168 // 读取成功后的回调 169 reader.onloadend = function () { 170 let result = this.result; 171 let img = new Image(); 172 img.src = result; 173 //判断图片是否大于100K,是就直接上传,反之压缩图片 174 if (this.result.length <= MAXSIZE) { 175 headerImage = this.result; 176 cb(dataURLtoFile(headerImage, imgName), { 177 headerImage, 178 imgName 179 }) 180 return 181 } else { 182 img.onload = function () { 183 compress(img, Orientation, cb); 184 } 185 } 186 } 187 } 188 } 189 export default upload
以上
以上是关于前端压缩图片代码,支持移动端和pc 端,还有拍照后获取到的照片的主要内容,如果未能解决你的问题,请参考以下文章
sign-canvas 一个基于canvas开发,封装于Vue组件的通用手写签名板(电子签名板),支持pc端和移动端;