小程序身份证照取景框+旋转处理+页面数据不刷新

需求说明:在采集用户的身份证件信息时,如果选择拍摄,增加取景框,拍摄完成后需要旋转角度再上传

之前查过相关资料,自我感觉,最简单的办法就直接使用camera组件内嵌cover-view组件,并根据点击事件获取拍照采集的类型是正面亦或是反面,从而修改取景框的背景图片显示

<!-- 上传身份证 -->
A页面
<view class="idPortrait">
     <text class="business-txt">上传身份证(人像面)</text>
     <view class="business-img">
         <image mode='aspectFill' src="{{image2}}"/>
     </view>
     <button class="business-btn" bindtap="idImage" data-type="idcard_front">上传身份证(人像面)</button>
 </view>
 <!-- 授权代理人身份证(国徽) -->
 <view class="nationalEmblem">
     <text class="business-txt">上传身份证(国徽面)</text>
     <view class="business-img">
         <image mode='aspectFill' src="{{image3}}"/>
     </view>
     <button class="business-btn" bindtap="idImage"  data-type="idcard_back">上传身份证(国徽面)</button>
 </view>

B页面
<camera 
    device-position="back" 
    flash="off" 
    binderror="cameraError" 
    class="cameraPhoto_camera" 
    style="height:{{cameraHeight}}px">
        <cover-view class="controls" style="width: 100%;height: 100%;">
            <cover-view class="controls2-bgcolor">
                <!-- 人像照 -->
                <cover-image wx:if='{{photoType == "idcard_front"}}' src="../../../resource/camera_front.png" />
                <!-- 国徽照 -->
                <cover-image wx:else src="../../../resource/camera_side.png" />
            </cover-view>
        </cover-view>
    </camera>
    <view class="cameraPhoto_bottom">
        <view class="wrap">
            <view bindtap="cancel">取消</view>
            <view bindtap="takePhoto">
                <image class="wrap_ok" src="../../../resource/camera_btn_icon.png"></image>
            </view>
            <view bindtap="chooseImage">相册</view>
        </view>
    </view>

由于不在同一个界面,又需要进行两次拍摄,所以,不能使用常规的页面跳转传值逻辑,我的方案是在B页面拍摄完成后,通过getCurrentPages()函数,在进行navigateBack返回A界面时,调用A页面的传值方法,以避免因为两次拍摄,而导致刷新页面数据的问题,逻辑如下

B界面
onLoad(options) {
        this.setData({
            photoType:options.type
        })
        if (wx.createCameraContext) {
            this.setData({
                cameraContext:wx.createCameraContext()
            })
        }
    },
    cameraError(e){
        const that = this;
        wx.getSetting({
            success(res) {
                if (!res.authSetting["scope.camera"]) {
                    wx.showModal({
                        title: '提示',
                        content: '请开启摄像头权限,否则无法拍照',
                        confirmText: '去开启',
                        success(res) {
                            if (res.confirm) {
                                wx.openSetting({
                                    success(res) {
                                        if (res.authSetting["scope.camera"]) {
                                            wx.navigateBack({
                                                delta: 1
                                            })
                                        } else {
                                            wx.navigateBack({
                                                delta: 1
                                            })
                                        }
                                    }
                                })
                            } else if (res.cancel) {
                                wx.navigateBack({
                                    delta: 1
                                })
                            }
                        }
                    })
                }
            }
        })
    },
    cancel(){
        wx.redirectTo({
            url: '../index'
        })
    },
    takePhoto(){
        let that = this
        this.data.cameraContext.takePhoto({
            quality: 'normal',
            success: (res) => {
                let pages = getCurrentPages();
                let prevPage = pages[pages.length - 2];
                wx.navigateBack({
                    delta: 1,
                    success: function () {
                        //调用前一个页面的上传图片方法,最后一个传参为是否需要旋转,只会针对拍照的图片进行旋转操作
                        prevPage.imgUpload(that.data.photoType,res.tempImagePath,true)
                    }
                })
            },
            fail: (err) => {
                wx.showToast({
                    title:'拍照失败,请检查系统是否授权',
                    icon: 'none',
                    duration: 1200
                })
            }
        })
    },
    chooseImage(){
        let that = this
        wx.chooseImage({
            count: 1,
            sizeType: ['original', 'compressed'],
            sourceType: ['album'],
            success: (res) =>  {
                let pages = getCurrentPages();
                let prevPage = pages[pages.length - 2];  
                wx.navigateBack({
                    delta: 1,
                    success: function () {
                        //调用前一个页面的上传图片方法。
                        prevPage.imgUpload(that.data.photoType,res.tempFilePaths[0],false)
                    }
                })
            },
            fail: (err) => {}
        });
    },
    /**
     * 生命周期函数--监听页面初次渲染完成
     */
    onReady() {

    },

    /**
     * 生命周期函数--监听页面显示
     */
    onShow() {
        let systemInfo = wx.getSystemInfoSync()
        this.setData({
            windowHeight:systemInfo.windowHeight,
            cameraHeight:systemInfo.windowHeight - 100
        })
    },

A界面
idImage: function (e) {
          var that = this
          wx.showActionSheet({
            itemList: ['拍照','从相册中选取'],
            itemColor: '#',
            success(res) {
                if (res.tapIndex === 0) {
                    //调用camera组件,即B界面
                    wx.navigateTo({
                      url: './index?type='+e.currentTarget.dataset.type,
                    });
                } else if (res.tapIndex === 1) {
                    wx.chooseImage({
                        count: 1,
                        sizeType: ["compressed"],
                        sourceType: ['album'],
                        success: function (res1) {
                          let filePath = res1.tempFilePaths[0]
                          that.imgUpload(e.currentTarget.dataset.type,filePath,false)
                        },
                        fail: function () {
                        }
                    })
                }
            }
          })
        },
        imgUpload(type,filePath,rotateval){
          let that = this;
          wx.showLoading({
            title:'信息采集中,请稍候',
            mask:true
          })
          if (rotateval) {
            let url = filePath;
            wx.getImageInfo({
                src: url,
                success:res=>{
                    let canvasContext = wx.createCanvasContext('my-canvas', this)
                    let width = res.width;
                    let height = res.height;
                    this.setData({
                        canvasWidth: width,
                        canvasHeight: height,
                    })
                    canvasContext.translate(width / 2, height / 2)
                    canvasContext.rotate(270 * Math.PI / 180);
                    canvasContext.drawImage(url, -width / 2, -height / 2, width, height);
                    canvasContext.draw(false, () => { // 将之前在绘图画到 canvas 中
                        setTimeout(function () {
                        //小程序版本中对于Canvas空间绘制图片,存在bug,效率比较低。canvasToTempFilePath接口最大的坑
                            wx.canvasToTempFilePath({ // 把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功。
                                canvasId: 'my-canvas',
                                success(res) {
                                  filePath = res.tempFilePath
                                  that.wxUploadApi(type,filePath)
                                }
                            }, this)// 在自定义组件下,当前组件实例的this,以操作组件内 canvas 组件
                        },300);
                    })
                }
            })
          }else{
            that.wxUploadApi(type,filePath)
          }
        },
        wxUploadApi(type,filePath){
          let that = this
          //此处的header和token属接口配置需要,按需添加
          let token = wx.getStorageSync("token");
          let header = {}
          header['Accept'] = 'application/json';
          header['WxAuthorization'] = token;
          if (type == 'idcard_front') {
            let formData = {
              'type':type,
              'isTemple':"false"
            }
            wx.uploadFile({
                url:that.data.baseUrl,
                filePath: filePath,
                name: 'file',
                header: header,
                formData:formData,
                withCredentials: true,
                success(res2) {
                  wx.hideLoading()
                  let data = JSON.parse(res2.data)
                  console.log(data);
                  if(data.code == 200) {
                    that.setData({
                      ....
                    })
                  }else{
                    wx.hideLoading()
                    wx.showToast({
                      icon:'error',
                      title: '上传身份证正面错误,请重新上传',
                      duration: 1200
                    })
                  }
                },
                fail(res) {
                  wx.hideLoading()
                  wx.showToast({
                    icon:'error',
                    title: '上传身份证正面失败,请重新上传',
                    duration: 1200
                  })
                    // reslogin(err)
                },
                complete() {
                }
            })
          }else if(type == 'idcard_back'){
            let formData = {
              'type':type,
            }
            wx.uploadFile({
                url:that.data.baseUrl,
                filePath: filePath,
                name: 'file',
                header: header,
                formData:formData,
                withCredentials: true,
                success(res2) {
                  wx.hideLoading()
                  let data = JSON.parse(res2.data)
                  if(data.code == 200) {
                    that.setData({
                      ...
                    })
                  }else{
                    wx.hideLoading()
                    wx.showToast({
                      icon:'error',
                      title: '上传身份证背面错误,请重新上传',
                      duration: 1200
                    })
                  }
                },
                fail(res) {
                  wx.hideLoading()
                  wx.showToast({
                    icon:'error',
                    title: '上传身份证背面失败,请重新上传',
                    duration: 1200
                  })
                },
                complete() {
                }
            })
          }
        },

然后在进行旋转过程后发现个极其恶心的bug,由于canvasToTempFilePath返回的是本地临时路径,无法查看图片是什么样的,只有传到后台服务器后,后台成功识别才能返回可以线上浏览的图片路径,我数次测试后台接口那边就是识别不通过,但只要不经过旋转,而直接拿相册或者拍照组件返回临时路径上传,就是正常的,后来我才发现经过画布组件旋转后上传的图片就是纯黑的,也曾试过清除画布内容、重置画面背景色等操作,结果就是,无效,只有再加上延时器后才能正常导出图片,我也是服了

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

妈耶,头发没了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值