vue调起手机摄像头上传图片,预览图片,删除图片

可以在手机上微信、支付宝、钉钉、浏览器中使用

用原生的input调起手机摄像头

   <input type="file" class="upImage" accept="image/*" @change="onFileChange" />

input的 capture=“camera” 这个属性 可以调起手机摄像头

但安卓和IOS 加上capture在不同场景下(微信、支付宝、钉钉)有的能同时调起相机和相册 有的只能调起相机

两者不加上capture则都可以调用相机和相册 目前没遇到调不起相册的情况

方法:

 onFileChange(e) {
      let file = e.target.files[0];
      //对文件检查
      let allType = "image/png,image/gif,image/jpeg,image/jpg,image/svg";
      if (allType.indexOf(file.type) == "-1") {
        this.$vux.toast.text("请选择图片文件");
        return false;
      }
      this.$vux.loading.show()
      
      let param = new FormData(); //创建form对象
      param.append("file", file); //通过append向form对象添加数据
      //这里的param已经是一个文件流了 但是我想压缩下图片再上传 如果不需要压缩 可以直接接口上传
      this.imgPreview(file);
    },
    
     // canvas压缩图片
  compress(img) {
      let canvas = document.createElement("canvas");
      let ctx = canvas.getContext("2d");
      let initSize = img.src.length;
      let width = img.width;
      let height = img.height;
      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(initSize);
      //进行最小压缩
      let ndata = canvas.toDataURL("image/jpeg", 0.2);  //这个0.2是可变的 数值越小 压缩的越厉害 很小图会失真 0.2还是可以接受的
      console.log("*******压缩后的图片大小*******", ndata.length);
      return ndata;
    },
    
    //压缩后的图片再转换成文件
  dataURLtoFile(dataurl, filename = "file") {
      let arr = dataurl.split(",");
      let mime = arr[0].match(/:(.*?);/)[1];
      let suffix = mime.split("/")[1];
      let bstr = atob(arr[1]);
      let n = bstr.length;
      let u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], `${filename}.${suffix}`, { type: mime });
    },
    
//上传文件
  imgPreview(file) {
      let that = this;
      // 判断是否支持FileReader
      if (!file || !window.FileReader) return;
      // 创建一个reader
      var reader = new FileReader();
      // 将图片转成base64格式
      reader.readAsDataURL(file);
      // 读取成功后的回调
      reader.onloadend = function() {
        let result = this.result;
        let img = new Image();
        img.src = result;
        // console.log("============未压缩图片===========");
        // console.log(result.length);

        img.onload = function() {
          let data = that.compress(img);//压缩
          // console.log(data.length);
          that.imgUrl = result;
          var formData = new FormData();

          let a = that.dataURLtoFile(data);//压缩后转换成文件
          let param = new FormData(); //创建form对象
          param.append("file", a); //通过append向form对象添加数据
          // return;
          let config = {
            headers: { "Content-Type": "multipart/form-data" }
          };
          //$http是封装的Axios
          that.$http
            .post("common/oss/upload", param, config)
            .then(res => {
              if (res.data.code = 200){
              that.localIdImgs.push(res.data.data.url);//上传成功会返回图片链接
              } 
              that.$vux.loading.hide();
            })
            .catch(err => {
              that.$vux.loading.hide();
            });
        };
      };
    },
  

后端接口只接收文件
因此 流程是 获取文件 >>转换成base64>>canvas压缩>>转化成文件>>接口上传

做出来的效果:
第一张
点击
33

在这里插入图片描述
在这里插入图片描述

预览图片

之前用的是vux的Previewer
官网上有一句描述:“注意避免使用过大图片,否则可能会出现卡顿黑屏的情况(尤其是在 Android 机子上) #2514。“

手机拍摄的图片 基本上都是几M的 iPhone手机拍出来的还有10M多的 压缩完也不小 亲测 卡 :(

于是用了最最简单的 点击放大预览

html:

<ul class="list-ul">
  <li class="list-li" v-for="(iu, index) in localIdImgs" :key="index">
     <!--显示的图片-->
     <a class="list-link" @click="show(index)">
         <img class="previewer-demo-img" :src="iu" />
     </a>
     <!--删除图标-->
     <span class="iconfont icon-shanchu" @click="delImage(index)">     </span>
  </li>
  
   <!--添加图片-->
   <li class="list-li-add" v-if="localIdImgs.length<5">
        <div class="list-default-img">
            <span class="iconfont icon-xiangji"></span>
            <span class>{{localIdImgs.length}}/5</span>
            <input type="file" class="upImage" accept="image/*" @change="onFileChange" />
        </div>
    </li>
</ul>

<!--显示预览的图片-->
<div v-if="imgShow" class="previewer" @click.stop="imgShow=false">
      <img class="previewer-demo-img" :src="previewerImg" />
</div>

js:

 data() {
    return {
      localIdImgs:[],//存图片链接
      imgShow:false,//显示预览
      previewerImg:'',//当前预览的图片
    }
 },
  methods: {
 //删掉图片
    delImage(index) {
      this.localIdImgs.splice(index, 1);
    },
  //预览图片
    show(index) {
      this.previewerImg = this.localIdImgs[index];
      this.imgShow = true;
    },



}

css:

.list-ul {
  padding: 0.32rem 0.24rem;
  padding-top: 0.1rem;
  height: 1.6rem;
  width: 6.9rem;
  .list-li {
    position: relative;
  }
  .list-li-add {
    width: 1.2rem;
    height: 1.2rem;
    border: 0.02rem dashed rgba(230, 230, 230, 1);
    position: absolute;
  }
  li {
    width: 1.2rem;
    height: 1.2rem;
    margin-right: 0.1rem;
    display: inline-block;
  }
  li:last-child {
    margin-right: 0;
  }
  .list-default-img {
    color: #ccc;
    text-align: center;
    padding-top: 0.1rem;
    position: relative;
    .iconfont {
      font-size: 0.48rem;
      display: block;
      height: 0.55rem;
    }
    span:nth-child(2) {
      font-size: 0.23rem;
    }

    .upImage {
      position: absolute;
      top: 0;
      left: 0;
      width: 1.2rem;
      height: 1.2rem;
      opacity: 0;
    }
  }
  .icon-shanchu {
    height: 0.32rem;
    position: absolute;
    top: -0.22rem;
    right: -0.12rem;
    background: #fff;
    z-index: 1000;
    border-radius: 100%;
  }
}
.previewer {
  z-index:1000;
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  background: #000;
  img {
    width: 100%;
    height: auto;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
  }
}

从网上找了很多方法 完成这个功能 记录一下( ̄▽ ̄")

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值