前端压缩图片代码,支持移动端和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

以上

猜你喜欢

转载自www.cnblogs.com/blackbentel/p/10725059.html