微信小程序原生 拍照 摄像上传 图片的截取等等 纯干货

  1. 原生微信小程序的拍照 截取
  2. 小程序的摄像(30S)
  3. 照片的截取
  4. 照片,视频的上传
.wxml
<view class="cameraParent" wx:if="{{picture}}">
   <view class="cameraTop">
       <p wx:if="{{dataNum == '4'}}">00:00:{{videoTimeText}}</p>
   </view>
   <canvas id="myCanvas" canvas-id="myCanvas" />
   <camera class="camera" device-position="{{devicePosition}}" binderror="error">
       <cover-view class="id_m">
           <cover-view class="texttop">
               <cover-image wx:if="{{dataNum == '1'}}" class="img" id="cover_image" src="/assets/img/idCardFront.png"></cover-image>
               <cover-image wx:elif="{{dataNum == '2'}}" class="img" id="cover_image" src="/assets/img/idCardBack.png"></cover-image>
               <cover-view wx:else class="img"></cover-view>
           </cover-view>
           <cover-view class="textcenter">
               <cover-view class="viewText" wx:if="{{dataNum == '1'}}">请将身份证头像徽面放在框内</cover-view>
               <cover-view class="viewText" wx:elif="{{dataNum == '2'}}">请将身份证国徽面放在框内</cover-view>
               <cover-view class="viewText" wx:elif="{{dataNum == '3'}}">请手持证件进行拍照</cover-view>
               <cover-view class="viewText  viewText1" wx:elif="{{dataNum == '4'}}">
                   <cover-view class="_text1">请在拍摄时朗读如下话术:</cover-view>
                   <cover-view class="_text1">我是XX(姓名),</cover-view>
                   <cover-view class="_text1">身份证身份证号是XXXXXX</cover-view>
               </cover-view>
           </cover-view>
       </cover-view>
   </camera>
   <view class="bodyRelease">
       <view class="_title" wx:if="{{dataNum == '1'|| dataNum == '2'||dataNum == '3'}}">照片</view>
       <view class="_title" wx:elif="{{dataNum == '4'&& !shoot }}">摄像</view>
       <view class="_title" wx:else>视频</view>
       <view class="butIncident">
           <view bindtap="backCamera" class="cancel">取消</view>
           <cview class="btnEvent">
               <image bindtap="shutter" class="{{down?'img2':''}} img1" src="/assets/img/one.png" mode="widthFix" lazy-load="false" wx:if="{{dataNum == '1'|| dataNum == '2'||dataNum == '3'}}"></image>
               <image bindtap="shutterstart" class="img1" src="/assets/img/two.png" mode="widthFix" lazy-load="false" wx:elif="{{dataNum == '4'&& !shoot }}"></image>
               <image bindtap="shutterend" class="img1" src="/assets/img/three.png" mode="widthFix" lazy-load="false" wx:else></image>
           </cview>
           <view bindtap="switch" class="_shift">
               <image class="img2" src="/assets/img/shift.png" lazy-load="false"></image>
           </view>
       </view>
   </view>
</view>
<view class="artificialCertification" wx:else>
   <view class="pic">
       <view class="exhibition">
           <image src="{{pic1}}" mode="widthFix" lazy-load="false" bindtap="chooseType" data-num='1' bindlongpress="handleLongPress"></image>
           <p>点击上传身份证人像面</p>
       </view>
       <view class="exhibition">
           <image src="{{pic2}}" mode="widthFix" lazy-load="false" bindtap="chooseType" data-num='2' bindlongpress="handleLongPress"></image>
           <p>点击上传身份证国徽面</p>
       </view>
       <view class="exhibition">
           <image src="{{pic3}}" mode="widthFix" lazy-load="false" bindtap="chooseType" data-num='3' bindlongpress="handleLongPress"></image>
           <p>点击上传手持身份证照片</p>
           <view class="_text">拍摄时,手持本人身份证,脸部清晰且不能被遮挡;确保身份证上的所有信息清晰可见、完整(没有被遮挡或者被手指捏住)</view>
       </view>
       <view class="exhibition" bindtap="chooseType" data-num='4' bindlongpress="handleLongPress">
           <image src="{{pic4}}" mode="widthFix" lazy-load="false" wx:if="{{!isIfVideo}}"></image>
           <video id="video" src="{{pic4}}" wx:else controls="{{true}}" show-center-play-btn='{{false}}' show-play-btn="{{false}}"></video>
           <p>点击上传手持身份证视频</p>
           <view class="_text">手持身份证拍摄视频,视频话术为:“我是XX(姓名),身份证身份证号是XXXXXX”</view>
       </view>
   </view>
   <view class="btn">
       <button bindtap="submit" disabled="{{disabledBut}}">提交</button>
       <button bindtap="backNext" class="back">返回</button>
   </view>
</view>
.scss
page {
    width: 100%;
    height: 100%;
}
.cameraParent {
    height: 100vh;
    width: 100vw;
    overflow: hidden;
    position: relative;
    .cameraTop {
        background: #000000;
        height: 6.6vh;
        width: 100vw;
        text-align: center;
        line-height: 6.6vh;
        font-family: PingFangSC-Regular;
        font-size: 40rpx;
        color: #ffffff;
    }
    #myCanvas {
        width: 100vw;
        height: 75vh;
        position: absolute;
        z-index: -999;
        opacity: 0;
    }
    .camera {
        height: 75vh;
        width: 100vw;
        z-index: 1;
        position: relative;
        .id_m {
            width: 100vw;
            height: 75vh;
            position: relative;
            .texttop {
                width: 100vw;
                .img {
                    display: block;
                    background-color: rgba(0, 0, 0, 0);
                    width: 92.3vw;
                    min-height: 58.42vw;
                    height: auto;
                    margin: 22% auto 0;
                    border-radius: 5%;
                }
            }
            .textcenter {
                position: absolute;
                bottom: 6.3vh;
                width: 100vw;
                display: flex;
                justify-content: center;
                .viewText {
                    height: auto;
                    display: inline-block;
                    font-family: PingFangTC-Regular;
                    font-size: 28rpx;
                    color: #ffffff;
                    background: rgba(0, 0, 0, 0.4);
                    border-radius: 16rpx;
                    padding: 20rpx 30rpx;
                    ._text1 {
                        line-height: 32rpx;
                    }
                }
            }
        }
    }

    .bodyRelease {
        background: #000000;
        height: 18.4vh;
        widows: 100vw;
        ._title {
            width: 100vw;
            font-family: PingFangTC-Regular;
            font-size: 28rpx;
            height: 6.3vh;
            line-height: 6.3vh;
            color: #29d1ff;
            text-align: center;
        }
        .butIncident {
            margin: 0 4vw;
            height: 10vh;
            display: flex;
            justify-content: space-between;
            .cancel {
                padding-left: 1vh;
                height: 10vh;
                width: 9vh;
                line-height: 10vh;
                font-family: PingFangTC-Regular;
                font-size: 30rpx;
                color: #ffffff;
            }
            .btnEvent {
                height: 10vh;
                width: 10vh;
                .img1 {
                    height: 10vh;
                    width: 10vh;
                    transform: scale(1);
                }
                .img2 {
                    transform: scale(0.85);
                }
            }
            ._shift {
                height: 10vh;
                width: 10vh;
                display: flex;
                .img2 {
                    margin: auto;
                    width: 80%;
                    height: 80%;
                }
            }
        }
    }
    .aa {
        height: 50vh !important;
        width: 100vw;
    }
}
.artificialCertification {
    width: 100%;
    min-height: 100%;
    padding: 28rpx 40rpx 96rpx 40rpx;
    box-sizing: border-box;
    .pic {
        width: 100%;
        .exhibition {
            display: flex;
            flex-direction: column;
            align-items: center;
            margin-top: 96rpx;
            image {
                width: 44vw;
                height: 27.85vw;
                display: block;
            }
            #video {
                width: 88vw;
                height: 44vw;
            }
            p {
                opacity: 0.6;
                font-family: PingFangSC-Regular;
                font-size: 26rpx;
                color: #233347;
                letter-spacing: 0.26rpx;
                text-align: justify;
                margin-top: 16rpx;
            }
            ._text {
                opacity: 0.8;
                font-family: PingFangSC-Regular;
                font-size: 28rpx;
                color: #233347;
                letter-spacing: 0.28rpx;
                text-align: justify;
                margin-top: 50rpx;
            }
        }
    }
    .btn {
        width: 100%;
        padding: 0 80rpx;
        box-sizing: border-box;
        margin-top: 96rpx;
        button {
            width: 100%;
            height: 90rpx;
            background: #3874f6;
            box-shadow: 0 4rpx 8rpx 0 rgba(56, 116, 246, 0.1);
            border-radius: 16rpx;
            font-family: PingFangSC-Regular;
            font-size: 28rpx;
            color: #ffffff;
            letter-spacing: 0.38rpx;
            line-height: 90rpx;
            padding: 0;
            margin-top: 64rpx;
            font-weight: 200;
        }
        .back {
            background: #f2f2f2;
            margin-top: 24rpx;
            color: #3874f6;
        }
    }
}
.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
    pic1: "../../assets/img/pic1.png",//为拍照时展示的图片
    pic2: "../../assets/img/pic2.png",//为拍照时展示的图片
    pic3: "../../assets/img/pic3.png",//为拍照时展示的图片
    pic4: "../../assets/img/pic4.png",//为录像时展示的图片
    isIfVideo: false, //控制视频是否上传
    arr: [undefined, undefined, undefined, undefined], //提交数据连接
    disabledBut: true, //是否提交数据
    picture: false, //是否启用相机
    devicePosition: "back", //摄像头的位置  front  back
    shoot: false, //是否开始拍摄
    videoTime: 30, //拍摄定时
    videoTimeText: 30, //时间同步器
    timeSetData: "", //定时器
    down: false, //是否点击拍照按钮
  },
  /***
   * 提交接口
   */
  submit() {
  	  /***
	   *确定相关照片都已经上传
	   *上传成功后会生产对应的文件路径
	   */
    if (!this.data.arr.includes(undefined)) {
      this.setData({
        disabledBut: true,//启动确定按钮禁用 防止多次点击
      });
      wx.showLoading({
        title: "提交中",
      });
      let params = {
        idCardFrontside: this.data.arr[0],
        idCardBackside: this.data.arr[1],
        lifePortrait: this.data.arr[2],
        authenticationVideo: this.data.arr[3],
      };
      //自己分装的ajax请求
      api.connect("/personalUserService/personalUsers/uploadAuthenticationInformatio",
        {
            data: params,
            method: "POST",
          }
        )//对应自己的接口对接
        .then((res) => {
       		//接口成功的操作
        })
        .catch(() => {
          //接口错误的操作
        });
    } else {
      let text = "上传图片或视频不能为空";
      switch (this.data.arr.indexOf(undefined)) {
        case 0:
          text = "身份证人像面不能为空";
          break;
        case 1:
          text = "身份证国徽面不能为空";
          break;
        case 2:
          text = "手持身份证照片不能为空";
          break;
        case 3:
          text = "手持身份证视频不能为空";
          break;
        default:
          text = "上传图片或视频不能为空";
          break;
      }
    }
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function () {
    this.ctx = wx.createCameraContext();//初始化 创建 camera 上下文 CameraContext 对象。
    this.ctx_A = wx.createCanvasContext("myCanvas"); //画布
  },
  /**
   * pic图片,视频上传还是预览
   */
  chooseType(e) {
    let num = e.currentTarget.dataset.num;
    if (this.data.arr[num - 1]) {
      if (num < 4) {
        wx.previewImage({
          current: this.data["pic" + num], // 当前显示图片的http链接
          urls: [this.data["pic" + num]], // 需要预览的图片http链接列表
        });
      } else {
      //如果是视屏则调去video播放
        let vid = wx.createVideoContext("video");
        vid.play();
      }
    } else {
      this.sourceSelection(num);
    }
  },

  /**
   * 长按事件
   * 重新上传
   */
  handleLongPress(e) {
    this.sourceSelection(e.currentTarget.dataset.num);
  },
  /**
   * 相机页面返回
   */
  backCamera() {
    this.setData({
      picture: false,
    });
    wx.hideLoading();
    clearTimeout(this.data.timeSetData);
  },
  /**
   * 点击自定义拍照按钮
   */
  shutter() {
    this.setData({
      down: true,
    });
    wx.showLoading({
      title: "上传压缩中...",
      mask: true,
    });
    this.ctx.takePhoto({
      quality: "high",
      success: (res) => {
        switch (this.data.dataNum) {
          case "1":
            this.generate(res.tempImagePath);
            break;
          case "2":
            this.generate(res.tempImagePath);
            break;
          case "3":
            wx.compressImage({
              src: res.tempImagePath, // 图片路径
              success: (item) => {
                this.getUrl(item.tempFilePath, 5);
              },
            });
            break;
          default:
            break;
        }
      },
    });
  },
  /**
   * 图片截取
   * 自定义计算位置  截取自己需要的那一部分图片
   */
  generate(imgSrc) {
    wx.createSelectorQuery()
      .select("#cover_image")
      .boundingClientRect((rect) => {
        this.ctx_A.drawImage(
          imgSrc,
          0,
          0,
          wx.getSystemInfoSync().windowWidth,
          wx.getSystemInfoSync().windowHeight * 0.75
        );
        this.ctx_A.draw(true, () => {
          wx.canvasToTempFilePath({
            //调用方法,开始截取
            x: rect.left,
            y: rect.top - wx.getSystemInfoSync().windowHeight * 0.066,
            width: rect.width,
            height: rect.height,
            destWidth: rect.width,
            destHeight: rect.height,
            canvasId: "myCanvas",
            quality: 1,
            success: (res) => {
              this.getUrl(res.tempFilePath, 5);
            },
          });
        });
      })
      .exec();
  },
  /**
   * 点击自定义摄像开始按钮
   */
  shutterstart() {
    wx.showLoading({
      title: "Loading...",
      mask: true,
    });
    this.ctx.startRecord({
      success: () => {
        this.setDataTime();
      },
    });
  },
  /**
   * 定时器
   * 防止视屏录制时间过长限制  
   * 原生限制30S
   */
  setDataTime() {
    this.data.timeSetData = setInterval(() => {
      if (this.data.videoTime < 0) {
        wx.showToast({
          title: "录制视频应小于30s",
          icon: "none",
          duration: 2000,
        });
        this.setData({
          shoot: false,
          videoTime: 30,
          videoTimeText: 30,
        });
        clearTimeout(this.data.timeSetData);
      } else {
        wx.hideLoading();
        this.setData({
          shoot: true,
          videoTimeText:
            this.data.videoTime.toString().length == 1
              ? `0${this.data.videoTime}`
              : this.data.videoTime,
          videoTime: --this.data.videoTime,
        });
      }
    }, 1000);
  },
  /**
   * 点击自定义摄像结束按钮
   */
  shutterend() {
    clearTimeout(this.data.timeSetData);
    wx.showLoading({
      title: "上传压缩中...",
      mask: true,
    });
    this.ctx.stopRecord({
      compressed: true,
      success: (res) => {
        this.setData({
          shoot: false,
        });
        this.getUrl(res.tempVideoPath, 4);
      },
    });
  },
  /**
   * 相机摄像头方向转换
   */
  switch() {
    this.setData({
      devicePosition: this.data.devicePosition == "back" ? "front" : "back",
    });
  },
  /**
   * 调取获取方式
   */
  sourceSelection(num = 1) {
    this.setData({
      picture: true,
      dataNum: num,
      devicePosition: "back",
      shoot: false,
      videoTimeText: 30,
      videoTime: 30,
      down: false,
    });
  },
  /**
   * 根据本地地址返回url
   */
  getUrl(file, fileType) {
    wx.getFileInfo({
      filePath: file,
      success(res) {
        console.log(res.size / 1024);
      },
    });
    wx.uploadFile({
      url: //自己的上传接口,
      header: {
        "Content-Type": "multipart/form-data",
        token: //,
      },
      filePath: file,
      name: "file",
      formData: {
        fileType: fileType,
      },
      success: (res) => {
        try {
          let data = JSON.parse(res.data);
          if (data.code == "2000") {
            switch (this.data.dataNum) {
              case "1":
                this.setData({
                  picture: false,
                  pic1: file,
                  ["arr[0]"]: data.data,
                });
                break;
              case "2":
                this.setData({
                  picture: false,
                  pic2: file,
                  ["arr[1]"]: data.data,
                });
                break;
              case "3":
                this.setData({
                  picture: false,
                  pic3: file,
                  ["arr[2]"]: data.data,
                });
                break;
              case "4":
                this.setData({
                  picture: false,
                  pic4: file,
                  isIfVideo: true,
                  ["arr[3]"]: data.data,
                });

                break;
              default:
                break;
            }
            this.getUrlOVer();
          }
        } catch (error) {
          wx.showToast({
            title: "提交失败",
            icon: "none",
            duration: 2000,
          });
          this.backCamera();
        }
      },
    });
  },
  /**
   * 返回url调取函数
   */
  getUrlOVer() {
    setTimeout(() => {
      this.backCamera();
      wx.showToast({
        title: `上传成功`,
        icon: "none",
        duration: 2000,
      });
      if (!this.data.arr.includes(undefined))
        this.setData({
          disabledBut: false,
        });
    }, 0);
  },
});

😋😋

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值