微信小程序拍照合成照片

在这里插入图片描述

<!--index.wxml-->
<view style='background-color:#000;' wx:if='{{isAuth}}'>
  <view class='page-main'>
    <view wx:if='{{!photoSrc}}'>
      <camera mode="normal" device-position="{{cameraDirec}}" flash="auto" binderror="cameraForbid" style="width: {{canvasWidth}}rpx; height: {{canvasHeight}}rpx;margin-left:{{canvasMaginLeft}}px">
      <cover-view class="camera-cover-box">
          <cover-image class="camera-top-img" src="../../images/top.png" style="width:100%; height:{{topImgHeight}}rpx;"/>
          <cover-image class="camera-bottom-img" src="../../images/bottom.png" style="width:100%; height:{{btmImgHeight}}rpx;"/>
        </cover-view>
      </camera>
      <!-- 测试专用代码 -->
      <!-- <view style='width:100%;height:600px;'></view> -->
      <!-- 测试专用代码 -->
    </view>
    <view wx:else class='preview'>
      <canvas canvas-id='canvas' style='width: {{canvasWidth}}rpx; height: {{canvasHeight}}rpx;margin-left:{{canvasMaginLeft}}px;'></canvas>
    </view>
  </view>
  <!-- 底部按钮 -->
  <view  wx:if='{{!photoSrc}}' class = 'page-bottom' style='height:{{btmHeight}}px'>
      <!-- 测试专用代码 -->
        <!-- <view class='btn-cell'>
            <button class='btn share-photo'  open-type="openSetting">设置</button> 
        </view> -->
      <!-- 测试专用代码 -->
    <button class='take-photo' bindtap="takePhoto"></button>
    <image src='https://edu.alva.com.cn/gq-image/change-drec.png'  class='change-camera-direc'  bindtap="changeCameraDirec"/>
  </view>
  <view wx:else class='page-bottom' style='height:{{btmHeight}}px' >
    <view class='page-canvas-btm'>  
      <view class='btn-cell' bindtap='backCamera'>
        <button class='btn back-camera'></button> 
        <view>返回</view>
      </view>
      <view class='btn-cell' bindtap='savePhoto'>
        <button class='btn save-photo'></button> 
        <view>保存</view>
      </view>
      <view class='btn-cell'>
          <button class='btn share-photo' open-type="share"></button> 
          <!-- <button class='btn share-photo' bindtap='sharePhoto'></button> -->
          <view>分享</view>
      </view>
      
    </view>
  </view>
  <!-- 底部按钮 -->
</view>
/**index.wxss**/
.container-box {
  background-color:#000;
}
.btn{
  border: none;
  outline: 0 none;
  color:#fff;
}

.camera-cover-box{
  position: relative;
  height: 100%;
}
.camera-cover-box .camera-bottom-img{
  position:absolute;
  left:0rpx;
  bottom: 0rpx;
}

.preview{
  position: relative;
  width:100%;
  height: 100%;
}

.page-bottom {
  position: fixed;
  bottom: 0rpx;
  left:0rpx;
  width: 100%;
  min-height: 100px;
  background-color: #000;
}

.page-bottom .change-camera-direc{
  width:49rpx;
  height: 38rpx;
  /* background:url('https://edu.alva.com.cn/gq-image/change-drec.png') no-repeat center; */
  /* background-size: cover; */
  position: absolute;
  left:80%;
  top:50%;
  transform: translate(0,-50%);
}

.page-bottom .take-photo{
  width:120rpx;
  height: 120rpx;
  background:url('https://edu.alva.com.cn/gq-image/camera2.png') no-repeat center;
  background-position: 0 0;
  background-size: 120rpx;
  border-radius: 50%;
  position: absolute;
  left:50%;
  top:50%;
  transform: translate(-50%,-50%);
}

.page-bottom .page-canvas-btm{
  display: flex;
  justify-content:space-around;
  align-items:center;
  color:#fff;
  font-size: 12px;
  height: 100%;
  vertical-align: middle;
}
.page-bottom .btn-cell{
  text-align: center;
}
.page-bottom .back-camera{
  background:url('https://edu.alva.com.cn/gq-image/back.png') no-repeat center;
  width: 50rpx;
  height: 50rpx;
  background-size: 50rpx;
}
.page-bottom .save-photo{
  background:url('https://edu.alva.com.cn/gq-image/save.png') no-repeat center;
  width: 50rpx;
  height: 50rpx;
  background-size: 50rpx;
}
.page-bottom .share-photo{
  background:url('https://edu.alva.com.cn/gq-image/share.png') no-repeat center;
  width: 50rpx;
  height: 50rpx;
  background-size: 50rpx;
}

.get-auth{
  position: fixed;
  top:50%;
  left:50%;
  transform: translate(-50%,-50%);
}

//index.js
//获取应用实例
const app = getApp()

Page({
  data: {
    photoSrc: '',// 照片的临时存储位置
    cameraDirec: 'back',//相机的方向

    screenWidth: 0,// 动态获取屏幕宽度
    screenHeight: 0,

    canvasImg: '', // 绘制的canvas的临时路径
    canvasHeight: 1280, // 相机以及绘制的canvas图片的高度
    canvasWidth: 720,
    canvasStandWHprop: 375 / 570,
    canvasMaginLeft: 0,

    topImgHeight: 390,  // 国旗图片的高
    btmImgHeight: 360, // 70周年图片的高
    // btmImgTop:0, // 70周年图片的top值(根据屏幕宽度动态计算得到,以保证心形的比例)

    btmHeight: 100, // 70周年图片以下部分的黑色区域的高度(当手机比较长的时候就需要动态计算以保证照片以下都是黑色的)
    isAuth: false
  },
  onLoad: function () {
    let self = this;
    wx.getSystemInfo({
      // 获取屏幕宽高后对整体显示的计算
      success: function (res) {
        const rpxToPx = res.windowWidth / 750; // px和rpx的单位转换
        const scale = res.windowWidth / 720; // 不同屏幕相对标准图的缩放值
        let screenWHprop = res.windowWidth / (res.windowHeight - 100);

        let canvasWidth = 720;
        let canvasHeight = 1280;
        let btmHeight = 100;
        let canvasMaginLeft = 0;

        console.log(screenWHprop, self.data.canvasStandWHprop)
        if (screenWHprop > self.data.canvasStandWHprop) {
          btmHeight = 100;
          canvasHeight = (res.windowHeight - 100) / rpxToPx;
          canvasWidth = canvasHeight * self.data.canvasStandWHprop;
          canvasMaginLeft = (res.windowWidth - canvasWidth * rpxToPx) / 2;
        } else {
          canvasWidth = res.windowWidth / rpxToPx;
          canvasHeight = (res.windowHeight - 100) / rpxToPx; //100为底部摄影部分的最小高度,canvasHeight的值是canvas高度的一般计算方法;
          let canvasMaxHeight = res.windowWidth / self.data.canvasStandWHprop / rpxToPx; //(要调整心的最大高度只需要调整375/570即可,这个数是canvas的标准宽高比)
          let flag = canvasHeight > canvasMaxHeight;
          canvasHeight = flag ? canvasMaxHeight : canvasHeight;
          btmHeight = flag ? (res.windowHeight - canvasHeight * rpxToPx) : 100;
        }
        let btmImgHeight = canvasWidth / 330 * 180;
        self.setData({
          screenWidth: res.windowWidth,
          screenHeight: res.windowHeight,
          canvasHeight: canvasHeight,
          canvasWidth: canvasWidth,
          btmHeight: btmHeight,
          btmImgHeight: btmImgHeight,
          canvasMaginLeft: canvasMaginLeft
        });
      },
    })
    wx.showShareMenu({
      withShareTicket: true
    })
  },
  onShow() {
    this.getAuth();
  },
  getAuth() {
    var that = this;
    wx.getSetting({
      success: (res) => {
        if (!res.authSetting['scope.camera']) {
          wx.showModal({
            title: '提示',
            content: '您好,请先授权相机和保存图片到相册的权限,然后再进行拍摄。',
            showCancel: false,
            success(res) {
              if (res.confirm) {//重新授权弹框用户点击了确定
                wx.openSetting({//进入小程序授权设置页面
                  success(settingdata) {
                    if (settingdata.authSetting['scope.writePhotosAlbum']) {
                      this.setData({
                        isAuth: true
                      })
                    }
                  }
                })//end openSetting
              }
            }// end success
          })
        } else {
          this.setData({
            isAuth: true
          })
        }
      }
    })
  },
  changeCameraDirec() {
    // 更改相机拍摄方向
    let currDirec = (this.data.cameraDirec === 'back') ? 'front' : 'back';
    this.setData({
      cameraDirec: currDirec
    });
  },
  takePhoto() {
    // 拍摄
    let self = this;
    const ctx = wx.createCameraContext();
    const canvas = wx.createCanvasContext('canvas');
    ctx.takePhoto({
      quality: 'high',
      success: (res) => {
        self.setData({
          photoSrc: res.tempImagePath
        });
        // 绘制canvas
        const rpxToPx = self.data.screenWidth / 750;
        let canvasHeight = this.data.canvasHeight * rpxToPx;
        let canvasWidth = this.data.canvasWidth * rpxToPx;
        let topImgHeight = this.data.topImgHeight * rpxToPx;
        let btmImgHeight = this.data.btmImgHeight * rpxToPx;
        canvas.drawImage(res.tempImagePath, 0, 0, canvasWidth, canvasHeight);
        canvas.drawImage('../../images/top.png', 0, 0, canvasWidth, topImgHeight);
        canvas.drawImage('../../images/bottom.png', 0, canvasHeight - btmImgHeight, canvasWidth, btmImgHeight);
        canvas.draw(true, setTimeout(function () {
          // 绘制canvas完成后把当前画布指定区域的内容导出生成指定大小的图片
          wx.canvasToTempFilePath({
            x: 0,
            y: 0,
            width: canvasWidth,
            height: canvasHeight,
            destWidth: canvasWidth * wx.getSystemInfoSync().pixelRatio,
            destHeight: canvasHeight * wx.getSystemInfoSync().pixelRatio,
            canvasId: 'canvas',
            quality: 1,
            success: function (res) {
              // 存储所生成图片的临时路径
              self.setData({
                canvasImg: res.tempFilePath
              });
            },
            fail: function (err) {
              console.log(err);
            }
          });
        }, 500));

      }
    })
  },
  backCamera() {
    this.setData({
      photoSrc: ''
    });
  },
  savePhoto() {
    console.log('save')
    let that = this;
    wx.saveImageToPhotosAlbum({
      filePath: that.data.canvasImg,
      success: function (data) {
        wx.showToast({
          title: '保存成功!',
          duration: 1000,
          success() {
          }
        });

        // setTimeout(function () {
        //   that.setData({
        //     photoSrc: ''
        //   });
        // }, 1010);
      },
      fail: function (err) {
        console.log(err);
        // if (err.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {
        wx.showModal({
          title: '提示',
          content: '您好,请先授权,再保存此图片。',
          showCancel: false,
          success(res) {
            if (res.confirm) {//重新授权弹框用户点击了确定
              wx.openSetting({//进入小程序授权设置页面
                success(settingdata) {
                  console.log(settingdata)
                  if (settingdata.authSetting['scope.writePhotosAlbum']) {//用户打开了保存图片授权开关
                    // wx.saveImageToPhotosAlbum({
                    //   filePath: benUrl,
                    //   success: function (data) {
                    //     wx.showToast({
                    //       title: '保存成功',
                    //       icon: 'success',
                    //       duration: 2000
                    //     })
                    //   },
                    // })
                  } else {//用户未打开保存图片到相册的授权开关
                    // wx.showModal({
                    //   title: '温馨提示',
                    //   content: '授权失败,请稍后重新获取',
                    //   showCancel: false,
                    // })
                  }
                }
              })//end openSetting
            }
          }// end success
        })
        // }
      }
    })
  },
  onShareAppMessage() {
    let self = this;
    return {
      title: '和国旗合影',
      path: '/pages/index/index',
      imageUrl: '',
      success: function (shareTickets) {
      },
      fail: function (res) {
        console.log(res + '失败');
      }
    }
  },
  sharePhoto() {
    let self = this;
    const rpxToPx = this.data.screenWidth / 750;
    let canvasHeight = this.data.canvasHeight * rpxToPx;

    const shareCanvas = wx.createCanvasContext('shareCanvas');
    // 绘制底图
    shareCanvas.drawImage(self.data.photoSrc, 0, 0, self.data.screenWidth, canvasHeight);
    shareCanvas.draw();
    // 添加文字描述
    shareCanvas.setTextAlign('center');
    shareCanvas.setFillStyle('#000');
    shareCanvas.setFontSize(22);
    shareCanvas.fillText('一起来和国旗合影', 300, 500);
    shareCanvas.stroke();
    shareCanvas.draw(true);
    // 绘制小程序码
    const qrImgSize = 180;
    shareCanvas.drawImage('../../images/codeId.jpg', (600 - qrImgSize) / 2, 530, qrImgSize, qrImgSize);
    shareCanvas.stroke();
    shareCanvas.draw(true);
    wx.canvasToTempFilePath({
      canvasId: 'shareCanvas',
    }, this).then(res => {
      return wx.saveImageToPhotosAlbum({
        filePath: res.tempFilePath,
      })
    }).then(res => {
      wx.showToast({
        title: '已保存到相册',
      })
    })

  },
  cameraForbid() {

  }
})

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值