vue使用exif获取图片旋转,压缩的示例代码


Posted in Vue.js onDecember 11, 2020
<template>
 <div>
  <input type="file" id="upload" accept="image" @change="upload" />
 </div>
</template>
<script>
export default {
 data() {
  return {
   picValue:{},
   headerImage:''
  };
 },
 components: {},
 methods: {
  upload(e) {
   console.log(e);
   let files = e.target.files || e.dataTransfer.files;
   if (!files.length) return;
   this.picValue = files[0];
   this.imgPreview(this.picValue);
  },
  imgPreview(file) {
   let self = this;
   let Orientation;
   //去获取拍照时的信息,解决拍出来的照片旋转问题
   self.Exif.getData(file, function() {
    Orientation = self.Exif.getTag(this, 'Orientation');
   });
   // 看支持不支持FileReader
   if (!file || !window.FileReader) return;

   if (/^image/.test(file.type)) {
    // 创建一个reader
    let reader = new FileReader();
    // 将图片2将转成 base64 格式
    reader.readAsDataURL(file);
    // 读取成功后的回调
    reader.onloadend = function() {
     let result = this.result;
     let img = new Image();
     img.src = result;
     //判断图片是否大于100K,是就直接上传,反之压缩图片
     if (this.result.length <= 100 * 1024) {
      self.headerImage = this.result;
      self.postImg();
     } else {
      img.onload = function() {
       let data = self.compress(img, Orientation);
       self.headerImage = data;
       self.postImg();
      };
     }
    };
   }
  },
  compress(img, Orientation) {
   let canvas = document.createElement('canvas');
   let ctx = canvas.getContext('2d');
   //瓦片canvas
   let tCanvas = document.createElement('canvas');
   let tctx = tCanvas.getContext('2d');
   let initSize = img.src.length;
   let width = img.width;
   let height = img.height;
   //如果图片大于四百万像素,计算压缩比并将大小压至400万以下
   let ratio;
   if ((ratio = (width * height) / 4000000) > 1) {
    console.log('大于400万像素');
    ratio = Math.sqrt(ratio);
    width /= ratio;
    height /= ratio;
   } else {
    ratio = 1;
   }
   canvas.width = width;
   canvas.height = height;
   //    铺底色
   ctx.fillStyle = '#fff';
   ctx.fillRect(0, 0, canvas.width, canvas.height);
   //如果图片像素大于100万则使用瓦片绘制
   let count;
   if ((count = (width * height) / 1000000) > 1) {
    console.log('超过100W像素');
    count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
    //      计算每块瓦片的宽和高
    let nw = ~~(width / count);
    let nh = ~~(height / count);
    tCanvas.width = nw;
    tCanvas.height = nh;
    for (let i = 0; i < count; i++) {
     for (let j = 0; j < count; j++) {
      tctx.drawImage(
       img,
       i * nw * ratio,
       j * nh * ratio,
       nw * ratio,
       nh * ratio,
       0,
       0,
       nw,
       nh
      );
      ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
     }
    }
   } else {
    ctx.drawImage(img, 0, 0, width, height);
   }
   //修复ios上传图片的时候 被旋转的问题
   if (Orientation != '' && Orientation != 1) {
    switch (Orientation) {
     case 6: //需要顺时针(向左)90度旋转
      this.rotateImg(img, 'left', canvas);
      break;
     case 8: //需要逆时针(向右)90度旋转
      this.rotateImg(img, 'right', canvas);
      break;
     case 3: //需要180度旋转
      this.rotateImg(img, 'right', canvas); //转两次
      this.rotateImg(img, 'right', canvas);
      break;
    }
   }
   //进行最小压缩
   let ndata = canvas.toDataURL('image/jpeg', 0.1);
   tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
   return ndata;
  },
  rotateImg(img, direction, canvas) {
   //最小与最大旋转方向,图片旋转4次后回到原方向
   const min_step = 0;
   const max_step = 3;
   if (img == null) return;
   //img的高度和宽度不能在img元素隐藏后获取,否则会出错
   let height = img.height;
   let width = img.width;
   let step = 2;
   if (step == null) {
    step = min_step;
   }
   if (direction == 'right') {
    step++;
    //旋转到原位置,即超过最大值
    step > max_step && (step = min_step);
   } else {
    step--;
    step < min_step && (step = max_step);
   }
   //旋转角度以弧度值为参数
   let degree = (step * 90 * Math.PI) / 180;
   let ctx = canvas.getContext('2d');
   switch (step) {
    case 0:
     canvas.width = width;
     canvas.height = height;
     ctx.drawImage(img, 0, 0);
     break;
    case 1:
     canvas.width = height;
     canvas.height = width;
     ctx.rotate(degree);
     ctx.drawImage(img, 0, -height);
     break;
    case 2:
     canvas.width = width;
     canvas.height = height;
     ctx.rotate(degree);
     ctx.drawImage(img, -width, -height);
     break;
    case 3:
     canvas.width = height;
     canvas.height = width;
     ctx.rotate(degree);
     ctx.drawImage(img, -width, 0);
     break;
   }
  },
  postImg() {
   //这里写接口

//打印的图片base64

   console.log('this.headerImage',this.headerImage);
   //接口 axios
  }
 }
};
</script>

要先运行

npm install exif-js --save

然后在main.js中添加

import Exif from 'exif-js'
Vue.use(Exif)
Vue.prototype.Exif = Exif

以上就是vue使用exif获取图片旋转,压缩的示例代码的详细内容,更多关于vue 图片旋转,压缩的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
Vue开发中常见的套路和技巧总结
Nov 24 Vue.js
VUE项目实现主题切换的多种方法
Nov 26 Vue.js
Vue router传递参数并解决刷新页面参数丢失问题
Dec 02 Vue.js
vue项目中openlayers绘制行政区划
Dec 24 Vue.js
Vue通过阿里云oss的url连接直接下载文件并修改文件名的方法
Dec 25 Vue.js
vue实现拖拽进度条
Mar 01 Vue.js
vue脚手架项目创建步骤详解
Mar 02 Vue.js
vue 中 get / delete 传递数组参数方法
Mar 23 Vue.js
vue使用Google Recaptcha验证的实现示例
Aug 23 Vue.js
vue 给数组添加新对象并赋值
Apr 20 Vue.js
vue 自定义的组件绑定点击事件
Apr 21 Vue.js
VUE解决跨域问题Access to XMLHttpRequest at
May 06 Vue.js
Vue 实现一个简单的鼠标拖拽滚动效果插件
Dec 10 #Vue.js
vuex页面刷新导致数据丢失的解决方案
Dec 10 #Vue.js
详解vue-cli项目在IE浏览器打开报错解决方法
Dec 10 #Vue.js
Vue+element-ui添加自定义右键菜单的方法示例
Dec 08 #Vue.js
vue添加自定义右键菜单的完整实例
Dec 08 #Vue.js
vue中如何自定义右键菜单详解
Dec 08 #Vue.js
基于vue与element实现创建试卷相关功能(实例代码)
Dec 07 #Vue.js
You might like
Terran兵种对照表
2020/03/14 星际争霸
PHP5 安装方法
2007/01/15 PHP
解析如何去掉CodeIgniter URL中的index.php
2013/06/25 PHP
Yii 2.0如何使用页面缓存方法示例
2017/05/23 PHP
Windows平台PHP+IECapt实现网页批量截图并创建缩略图功能详解
2019/08/02 PHP
Node.js中使用mongoskin操作mongoDB实例
2014/09/28 Javascript
JS判断iframe是否加载完成的方法
2016/08/03 Javascript
Javascript 创建类并动态添加属性及方法的简单实现
2016/10/20 Javascript
Bootstrap CSS组件之按钮组(btn-group)
2016/12/17 Javascript
微信小程序通过api接口将json数据展现到小程序示例
2017/01/20 Javascript
JavaScript拖动层Div代码
2017/03/01 Javascript
JavaScript实现小球沿正弦曲线运动
2020/09/07 Javascript
js实现跟随鼠标移动的小球
2019/08/26 Javascript
layui表格内容溢出的解决方法
2019/09/06 Javascript
微信小程序实现蒙版弹出窗功能
2019/09/17 Javascript
Element InfiniteScroll无限滚动的具体使用方法
2020/07/27 Javascript
vue使用canvas实现移动端手写签名
2020/09/22 Javascript
[10:42]Team Liquid Vs Newbee
2018/06/07 DOTA
python中的reduce内建函数使用方法指南
2014/08/31 Python
基于Python __dict__与dir()的区别详解
2017/10/30 Python
查看python下OpenCV版本的方法
2018/08/03 Python
Python3 A*寻路算法实现方式
2019/12/24 Python
2020版Python学习路线图(附学习资料)
2020/09/15 Python
Ever New美国:澳大利亚领先的女装时尚品牌
2019/11/28 全球购物
求职自荐书范文
2013/12/04 职场文书
校园门卫岗位职责
2013/12/09 职场文书
房屋公证委托书
2014/04/03 职场文书
大专应届毕业生求职信
2014/07/15 职场文书
自愿解除劳动合同协议书
2014/09/11 职场文书
2014个人年度工作总结
2014/12/15 职场文书
工程部部长岗位职责
2015/02/12 职场文书
2015毕业生实习期工作总结
2015/04/09 职场文书
总经理司机岗位职责
2015/04/10 职场文书
八年级数学教学反思
2016/02/17 职场文书
高中政治教师教学反思
2016/02/23 职场文书
Python面向对象编程之类的概念
2021/11/01 Python