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解决移动端弹窗滚动穿透问题
Dec 15 Vue.js
vue实现防抖的实例代码
Jan 11 Vue.js
如何使用RoughViz可视化Vue.js中的草绘图表
Jan 30 Vue.js
vue backtop组件的实现完整代码
Apr 07 Vue.js
vue实现简单数据双向绑定
Apr 28 Vue.js
vue中利用mqtt服务端实现即时通讯的步骤记录
Jul 01 Vue.js
Vue3.0中Ref与Reactive的区别示例详析
Jul 07 Vue.js
Vue3如何理解ref toRef和toRefs的区别
Feb 18 Vue.js
vue整合百度地图显示指定地点信息
Apr 06 Vue.js
使用vuex-persistedstate本地存储vuex
Apr 29 Vue.js
vue实现登陆页面开发实践
May 30 Vue.js
VUE递归树形实现多级列表
Jul 15 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
PHP获得用户使用的代理服务器ip即真实ip
2006/12/31 PHP
PHP错误抑制符(@)导致引用传参失败Bug的分析
2011/05/02 PHP
wordpress自定义url参数实现路由功能的代码示例
2013/11/28 PHP
php 解决substr()截取中文字符乱码问题
2016/07/18 PHP
php中通用的excel导出方法实例
2017/12/30 PHP
关于B/S判断浏览器断开的问题讨论
2008/10/29 Javascript
jQuery+css实现图片滚动效果(附源码)
2013/03/18 Javascript
一个JS的日期格式化算法示例
2013/07/31 Javascript
浅谈JavaScript中指针和地址
2015/07/26 Javascript
JS实现获取键盘按下的按键并显示在页面上的方法
2015/11/04 Javascript
AngularJS中的$watch(),$digest()和$apply()区分
2016/04/04 Javascript
41个Web开发者必须收藏的JavaScript实用技巧
2016/07/22 Javascript
javascript对浅拷贝和深拷贝的详解
2016/10/14 Javascript
vue中使用ueditor富文本编辑器
2018/02/08 Javascript
Vue中使用Sortable的示例代码
2018/04/07 Javascript
node puppeteer(headless chrome)实现网站登录
2018/05/09 Javascript
浅谈React之状态(State)
2018/09/19 Javascript
vue中对象数组去重的实现
2020/02/06 Javascript
在Vue中使用CSS3实现内容无缝滚动的示例代码
2020/11/27 Vue.js
Django集成百度富文本编辑器uEditor攻略
2014/07/04 Python
遍历python字典几种方法总结(推荐)
2016/09/11 Python
Python面向对象class类属性及子类用法分析
2018/02/02 Python
python多维数组切片方法
2018/04/13 Python
pygame游戏之旅 计算游戏中躲过的障碍数量
2018/11/20 Python
Python中类的创建和实例化操作示例
2019/02/27 Python
QML使用Python的函数过程解析
2019/09/26 Python
Python日志syslog使用原理详解
2020/02/18 Python
世界上最全面的汽车零部件和配件集合:JC Whitney
2016/09/04 全球购物
德国机车企业:FC-Moto
2017/10/27 全球购物
Stefania Mode美国:奢华设计师和时尚服装
2018/01/07 全球购物
澳大利亚最便宜的网上药房:Chemist Warehouse
2020/01/30 全球购物
《和我们一样享受春天》教学反思
2014/02/07 职场文书
领导走群众路线整改措施思想汇报
2014/10/12 职场文书
2015年物业管理员工工作总结
2015/10/15 职场文书
年终工作总结范文
2019/06/20 职场文书
python代码实现扫码关注公众号登录的实战
2021/11/01 Python