美文网首页
小程序调用摄像头拍照和上传图片

小程序调用摄像头拍照和上传图片

作者: 陈大帅 | 来源:发表于2023-01-04 16:44 被阅读0次

    一、微信小程序调用摄像头实现拍照功能

    微信小程序开发文档
    首先,需要用户授权摄像头权限,这一步是必须的

    具体步骤:

    1、获取用户当前授权状态,看是否已经授权,如果已经授权直接显示摄像头
    2、如果用户还没有授权,则调起授权弹框,用户允许授权则显示摄像头
    3、如果用户不允许,则提示用户去设置页面打开摄像头权限

    用户授权之后,就可以进行拍摄了,微信的camera组件无法显示为圆形,我这里是用一张图片遮盖了

    上代码:

    wxml:

    <view class='camera'>
      <image src="/images/border.png" mode="widthFix"></image>
      <camera wx:if="{{isAuth}}" device-position="back" flash="off" binderror="error"></camera>
    </view>
    <button class="takePhoto" type="primary" bindtap="takePhoto">拍照</button>
    

    wsss:

    .camera {
      width: 430rpx;
      height: 430rpx;
      border-radius: 50%;
      margin: 20px auto 0;
      position: relative;
    }
    
    .camera image {
      position: absolute;
      width: 100%;
      height: 100%;
      z-index: 10;
    }
    
    .camera camera {
      width: 428rpx;
      height: 428rpx;
    }
    
    button.takePhoto:not([size='mini']) {
      position: fixed;
      bottom: 0;
      left: 0;
      width: 100vw;
      height: 90rpx;
      border-radius: 0;
    }
    

    js:

    Page({
      data: {
        isAuth: false,
        src: ''
      },
      onLoad() {
        const _this = this
        wx.getSetting({
          success: res => {
            if (res.authSetting['scope.camera']) {
              // 用户已经授权
              _this.setData({
                isAuth: true
              })
            } else {
              // 用户还没有授权,向用户发起授权请求
              wx.authorize({
                scope: 'scope.camera',
                success() { // 用户同意授权
                  _this.setData({
                    isAuth: true
                  })
                },
                fail() { // 用户不同意授权
                  _this.openSetting().then(res => {
                    _this.setData({
                      isAuth: true
                    })
                  })
                }
              })
            }
          },
          fail: res => {
            console.log('获取用户授权信息失败')
          }
        })
      },
    
      // 打开授权设置界面
      openSetting() {
        const _this = this
        let promise = new Promise((resolve, reject) => {
          wx.showModal({
            title: '授权',
            content: '请先授权获取摄像头权限',
            success(res) {
              if (res.confirm) {
                wx.openSetting({
                  success(res) {
                    if (res.authSetting['scope.camera']) { // 用户打开了授权开关
                      resolve(true)
                    } else { // 用户没有打开授权开关, 继续打开设置页面
                      _this.openSetting().then(res => {
                        resolve(true)
                      })
                    }
                  },
                  fail(res) {
                    console.log(res)
                  }
                })
              } else if (res.cancel) {
                _this.openSetting().then(res => {
                  resolve(true)
                })
              }
            }
          })
        })
        return promise;
      },
    
      takePhoto() {
        const ctx = wx.createCameraContext()
        ctx.takePhoto({
          quality: 'high',
          success: (res) => {
            this.setData({
              src: res.tempImagePath
            })
            wx.previewImage({
              current: res.tempImagePath, // 当前显示图片的http链接
              urls: [res.tempImagePath] // 需要预览的图片http链接列表
            })
          }
        })
      }
    })
    

    二、微信小程序实现图片上传

    微信小程序实现图片上传

    首先是静态布局和样式部分

    .wxml:

    <view class='load-img'>
        <view class='load-box'>
          <view class='img-item' wx:for="{{fileList}}" wx:key="index" >
            <image src="{{item.path}}" data-src="{{item}}" mode="aspectFill" data-list="{{fileList}}" bindtap=""></image>
            <icon class='icon' type="clear" size="20" color='#EF4444' catchtap='_onDelTab' data-idx="{{index}}" wx:if="{{!prevent}}"/>
          </view>
          <image class='img-add' bindtap='_addImg' wx:if="{{!prevent}}"></image>
        </view>
      </view>
    

    .wxss:

    /* 上传图片 */
    .load-name {
        height: 80rpx;
        line-height: 80rpx;
        font-size: 30rpx;
      }
      .load-box {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
      }
      .img-item, .img-add {
        position: relative;
        width: 140rpx;
        height: 140rpx;
        margin: 20rpx;
      }
      .img-add {
        border: 1px solid #ccc;
      }
      .img-add:after{
        width: 1rpx;
        height: 50rpx;
        content: " ";
        position: absolute;
        top: 50%;
        left: 50%;
        -webkit-transform: translate(-50%, -50%);
        -ms-transform: translate(-50%, -50%);
        transform: translate(-50%, -50%);
        background-color: #ccc;
      }
      .img-add:before{
        position: absolute;
        top: 50%;
        right: 31%;
        width: 50rpx;
        height: 1rpx;
        content: " ";
        display: inline-block;
        background-color: #ccc;  
      }
      
      .img-item {
        margin-right: 20rpx;
      }
      .img-item image {
        width: 100%;
        height: 100%;
        border-radius: 10rpx;
      }
      .icon {
        position: absolute;
        top: 0;
        right: 0;
      }
    

    以上这些基本代码就可以完成图片上传,显示,删除等样式布局

    下面是js的部分,我已详细备注~~~

    先来看下完整的代码

    /**
     * 小程序图片上传
     * 组件接受参数
     * fileList  图片数组
     * prevent 控制是否可新增
     * 方法
     * bindimageChange 选择图片后触发
     * bindimageDel  删除图片后触发
     * 
     */
    const app = getApp();
    Component({
      properties: {
        fileList: {
          type: Array
        },
        prevent: {
          type: Boolean,
          value: false
        }
      },
      data: {
        fileList: []
      },
      ready() {},
      methods: {
        // 点击加号进入手机相册,并进行图片选择
        _addImg() {
          let _this = this;
          // 此方法为微信小程序自带api 详情访问https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.chooseImage.html
          wx.chooseImage({
            count: 5,
            success(res) {
              //此处会返回图片暂存路径和文件大小
              const data = res.tempFiles;
              _this.setFile(data)
            }
          })
        },
        setFile (data) {
          // 将wx.chooseImage返回的数据进行扩展
          data.map((item, index) => {
            // 通过路径截取文件后缀名
            const fileFormat = item.path.substring(item.path.lastIndexOf(".") + 1, item.path.length);
            // wx.getFileSystemManager()小程序文件管理器api,可以将通过文件路径将其转换成64编码
            const fileManager = wx.getFileSystemManager();
            const base64 = fileManager.readFileSync(item.path, 'base64');
            item.fileContent = base64;
            item.fileSize = item.size;
            // 通过时间获取随机13位随机数并且拼接文件后缀进行文件命名
            item.fileName = this.getFileName(13) + '.' + fileFormat;
            // 此处操作是用来进行选中图片显示的,只有这样拼接才能显示base64编码的路径
            item.path = `data:image/${fileFormat};base64,${base64}`;;
          })
          this.setData({ 
            fileList: this.data.fileList.concat(data)
          });
          // 此处操作是用来将获取到的文件数据传递给父组件进行文件上传
          this.triggerEvent('imageChange', this.data.fileList)
        },
        // 随机生成文件名
        getFileName (m) {
          m = m > 13 ? 13 : m;
          var num = new Date().getTime();
          return num.toString().substring(13 - m);
        },
        点击进行图片删除
        _onDelTab(e) {
          // 获取图片索引
          let idx = e.currentTarget.dataset.idx;
          let delFile = this.data.fileList[idx];
          console.log(delFile);
          this.data.fileList.splice(idx, 1);
          this.setData({
            fileList: this.data.fileList
          })
          this.triggerEvent('imageDel', delFile);
        }
    })
    

    代码里对代码的备注已经很明确了,大家仔细扒一下,根据的自己的项目进行相应的调整,基本上都是没问题的,不要直接直接粘贴不复置,我是直接在我的项目中直接拿过来的代码,直接粘贴复制肯定是不行的!!!

    需要注意的是这里

    image.png

    通常在真机上点击选中图片后wx.chooseImage方法中返回的文件路径是wxfile:开头的路径,这样的路径想直接转成base64,上面的方式是可以实现的,我也是查了很多资料才找到的解决办法。

    再一个需要注意的是image src属性想显示base64格式的图片要进行字符串拼接才可以正常显示如下图


    image.png

    参考原文链接1
    参考原文链接2

    相关文章

      网友评论

          本文标题:小程序调用摄像头拍照和上传图片

          本文链接:https://www.haomeiwen.com/subject/jfarcdtx.html