vue 移动端拍照压缩base64格式上传

啰嗦两句,因最近有个小项目要做一个拍照上传头像的功能,做的过程中出现了一些问题,针对这些问题做一下总结分享

问题:

  1.图片转base64

  2.手机拍照在ios和小米等手机下会旋转

  3.图片的压缩

  4.手机像素太大,进行一个等比缩放上传

啰嗦完了,上代码

  

<template>
  <div id="face">
    <div class="faceBox">
      <img src="" alt="" id="faceImg" ref="faceImg">
    </div>
    <p>请拍摄清晰的全部人脸信息以方便您的进场</p>
    <img src="../../static/images/example.png" alt="" class="example">
    <div class="startFaceBtn" v-show="!openVideo">
      <button class="startFace">开始拍摄</button>
      <input type="file" id="upimg" accept="image/*" @change="upLoad">
    </div>
    <button class="startFace" v-show="openVideo" @click="submit">开始上传</button>
  </div>
</template>

上面是页面的布局

关于处理图片旋转的问题需要使用 Exif

npm install exif-js

然后在main.js中引入

import EXIF from ‘exif-js‘
Vue.prototype.Exif = EXIF
<script>
import { Indicator } from ‘mint-ui‘;
export default {
  name: ‘face‘,
  data() {
    return {
      openVideo: false,
      imgUrl: null,
    }
  },
  mounted() {
  },
  methods: {
    upLoad(e) {
      let files = e.target.files || e.dataTransfer.files;
      if (!files.length) return;
      this.picavalue = files[0];
      console.log(this.picavalue.size / 1024);
      if (this.picavalue.size / 1024 > 10000) {
        this.$message({
          message: "图片过大不支持上传",
          type: "warning"
        });
      } else {
        this.imgPreview(this.picavalue);
      }
    },
    imgPreview(file, callback) {
      let that= this;
      let Orientation
//这里的Exif是判断图片旋转的
      that.Exif.getData(file, function () {
        Orientation = that.Exif.getTag(file, ‘Orientation‘);
      });
      if (!file || !window.FileReader) return;
      if (/^image/.test(file.type)) {
        let reader = new FileReader();
        reader.readAsDataURL(file)
        reader.onloadend = function() {
          let result = this.result;
          let img = new Image();
          img.src = result;
          img.onload = () => {
            let data = that.compress(img, Orientation);
            that.imgUrl = result;
            that.imgUrl = data
            console.log(data)
            that.$refs.faceImg.src = data
            that.openVideo = true
          };
        };
      }
    },
    compress(img, Orientation) {
      let canvas = document.createElement("canvas");
      let ctx = canvas.getContext("2d");
      let initSize = img.src.length;
      let width = img.width/3.5;
      let height = img.height/3.5;
      canvas.width = width;
      canvas.height = height;
      ctx.fillStyle = "#fff";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, 0, 0, width, height);
      console.log(Orientation)
//处理ios手机旋转角度问题
      if (navigator.userAgent.match(/iphone/i)) {
        if(Orientation != "" && Orientation != 1){
          switch(Orientation){
          case 6:
            this.rotateImg(img,‘left‘,canvas);
            break;
          case 8:
            this.rotateImg(img,‘right‘,canvas);
            break;
          case 3:
            this.rotateImg(img,‘right‘,canvas);//转两次
            this.rotateImg(img,‘right‘,canvas);
            break;
          }
        }
      }else{
//处理其安卓类手机图片旋转的问题
        if(Orientation != "" && Orientation != 1){
          switch(Orientation){
            case 6:
              this.rotateImg(img,‘left‘,canvas);
              break;
            case 8:
              this.rotateImg(img,‘right‘,canvas);
              break;
            case 3:
              this.rotateImg(img,‘right‘,canvas);
              this.rotateImg(img,‘right‘,canvas);
              break;
          }
        }
      }
      // ndata 为base64格式的图片上传时可直接使用,根据清晰度的要求进行调整,这里我用的是0.4
      var ndata = canvas.toDataURL("image/jpeg", 0.4);
      return ndata;
    },
    rotateImg (img, direction,canvas) {
      //最小与最大旋转方向,图片旋转4次后回到原方向
      const min_step = 0;
      const max_step = 3;
      if (img == null)return;
      //img的高度和宽度不能在img元素隐藏后获取,否则会出错
      //这里因为图片像素太大进行了一个3.5倍的缩放
      let height = img.height/3.5;
      let width = img.width/3.5;
      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‘);
      console.log(step)
      switch (step) {
        case 0:
        canvas.width = width;
        canvas.height = height;
        ctx.drawImage(img, 0, 0, width, height);
        break;
        case 1:
        canvas.width = height;
        canvas.height = width;
        ctx.rotate(degree);
        ctx.drawImage(img, 0, -height, width, height);
        break;
        case 2:
        canvas.width = width;
        canvas.height = height;
        ctx.rotate(degree);
        ctx.drawImage(img, -width, -height, width, height);
        break;
        case 3:
        canvas.width = height;
        canvas.height = width;
        ctx.rotate(degree);
        ctx.drawImage(img, -width, 0, width, height);
        break;
      }
    },
    submit() {
      //点击按钮处理上传图片的逻辑就行了,这里就不做介绍了
    }
  }
}
</script>

文章参照:https://blog.csdn.net/xiaogezl/article/details/70156500

原文地址:https://www.cnblogs.com/zengkai/p/11132035.html

时间: 2024-11-06 07:44:19

vue 移动端拍照压缩base64格式上传的相关文章

php图片处理之图片转为base64格式上传

我们在开发系统时,处理图片上传是不可避免的,使用thinkphp的肯定很熟悉 import("@.ORG.UploadFile"); 的上传方式. 今天我们来讲一个使用html5 base64上传图片的方法. 其实就是用到html5 FileReader的接口,既然是html5的,所支持的浏览器我就不多说啦,老生常谈的问题了,远离IE,珍惜生命. 先扔个demo出来给大伙体验体验哈. http://t.lanchenglv.com/lan/index.php/Base64/images

android 拍照或者图库选择 压缩后 图片 上传

通过拍照或者从相册里选择图片通过压缩并上传时很多应用的常用功能,记录一下实现过程 一:创建个临时文件夹用于保存压缩后需要上传的图片 /** * path:存放图片目录路径 */ private String path = Environment.getExternalStorageDirectory().getPath() + "/XXX/"; /** * saveCatalog:保存文件目录 */ private File saveCatalog; /** * saveFile:保存

文件上传三:base64编码上传

介绍三种上传方式: 文件上传一:伪刷新上传 文件上传二:FormData上传 文件上传三:base64编码上传 Flash的方式也玩过,不喜欢不拿来说了. 优点: 1.浏览器可以马上展示图像,不需要先上传到服务端,减少服务端的垃圾图像 2.前端可以压缩.处理后上传到服务端,减少传输过程中的等待时间和服务器压力 缺点: 1.生成编码后保存成图片,倘若不做处理,会比原来的图片容量大,具体原因,搜索关键词:Base64编码为什么会使数据量变大 2.图片越大生成的编码越多,编码越多开发者工具中查看它时卡

HTML5+Canvas+jQuery调用手机拍照功能实现图片上传(二)

上一篇只讲到前台操作,这篇专门涉及到Java后台处理,前台通过Ajax提交将Base64编码过的图片数据信息传到Java后台,然后Java这边进行接收处理,通过对图片数据信息进行Base64解码,之后使用流将图片数据信息上传至服务器进行保存,并且将图片的路径地址存进数据库.ok,废话不多说了,直接贴代码吧. 1.前台js代码: $.ajax({ async:false,//是否异步 cache:false,//是否使用缓存 type: "POST", data:{fileData:fi

Ali OSS服务端签名直传并设置上传回调

服务端签名直传并设置上传回调 背景 请参考 Web端直传实践 里的背景介绍. 当采用服务端签名后直传方案后,问题来了,用户上传数据后,很多场景下,应用服务器都要知道用户上传了哪些文件,文件名字,甚至如果是图片的话,图片的大小等.为此OSS开发了上传回调功能. 用户的请求逻辑 用户向应用服务器取到上传policy和回调设置. 应用服务器返回上传policy和回调. 用户直接向OSS发送文件上传请求. 等文件数据上传完,OSS给用户Response前,OSS会根据用户的回调设置,请求用户的服务器.

node复制文件夹,压缩zip,上传

一:用到的模块和简单介绍 npm文档:request :node请求的模块,可以给用程序请求服务器的接口https://www.npmjs.com/package/requestfs:读写文件的,很常用https://www.npmjs.com/package/fspath:路径,各种给文件夹弄路径什么的https://www.npmjs.com/package/pathjs-cookie:获取cokie的,在请求的时候需要用到https://www.npmjs.com/package/js-c

js图片前端压缩多图上传(旋转其实已经好了只是手机端有问题要先压缩再旋转)

var filechooser = document.getElementById("choose"); // 用于压缩图片的canvas var canvas = document.createElement("canvas"); var ctx = canvas.getContext('2d'); // 瓦片canvas var tCanvas = document.createElement("canvas"); var tctx = tC

[转]如何使用multipart/form-data格式上传文件

form表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码.默认情况,这个编码格式是"application/x-www-form-urlencoded",不能用于文件上传:只有使用了multipart/form-data,才能完整的传递文件数据. 有时,在网络编程过程中需要向服务器上传文件.Multipart/form-data是上传文件的一种方式. Multipart/form-data其实就是浏览器用表单上传文件的

如何使用multipart/form-data格式上传文件(POST请求时,数据是放在请求体内,而不是请求头内,在html协议中,用 “\r\n” 换行,而不是 “\n”)

在网络编程过程中需要向服务器上传文件.Multipart/form-data是上传文件的一种方式. Multipart/form-data其实就是浏览器用表单上传文件的方式.最常见的情境是:在写邮件时,向邮件后添加附件,附件通常使用表单添加,也就是用multipart/form-data格式上传到服务器. 表单形式上传附件 具体的步骤是怎样的呢? 首先,客户端和服务器建立连接(TCP协议). 第二,客户端可以向服务器端发送数据.因为上传文件实质上也是向服务器端发送请求. 第三,客户端按照符合“m