收藏
回答

wx.chooseMedia调用相机后怎么添加水印?

WXML:
 <view class="right-section" bindtap="takesfzBack">
          <image wx:if="{{ifphotosfzBack}}" class="section-image" style="height: 12vh;" src="/images/sfzBack.png" mode="" />
          <image wx:else class="section-image" src="{{photosfzBack}}"></image>
          <canvas id="myCanvas"  canvas-id="myCanvasId"></canvas>
          <view>上传身份证背面</view>
        </view>

JS:
onLoad() {
    this.setData({ pageLoaded: false });
  },
  onReady() {
    const query = wx.createSelectorQuery();
    query.select('#myCanvas').fields({ node: true }).exec((res) => {
      if (res && res.length > 0) {
        this.myCanvas = res[0].node;
        this.setData({ pageLoaded: true });
      } else {
        console.error('未找到具有 id="myCanvas" 的元素');
      }
    });
  },
 takesfzBack() {
    if (this.data.pageLoaded) {
      // 调用系统相机或相册选择媒体文件
      wx.chooseMedia({
        count: 1,
        mediaType: ['image'],
        sourceType: ['camera'],
        success: (res) => {
          if (res.tempFiles && res.tempFiles.length > 0) {
            this.setData({
              ifphotosfzBack: false,
            });
            const tempFilePath = res.tempFiles[0].tempFilePath;
            this.addWatermark(tempFilePath);
            console.log('照片路径:', res.tempFiles[0].tempFilePath);
          } else {
            console.error('未获取到照片路径');
          }
        },
        fail: (err) => {
          console.error('选择媒体文件失败:', err);
        },
      });
    } else {
      console.error('页面尚未完全加载,无法执行操作。');
    }
  },
  addWatermark(imagePath) {
    if (this.myCanvas) {
      const date = new Date();
      const formattedDate = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
      const ctx = this.myCanvas.getContext('2d');
      const img = new Image();
      img.src = imagePath;
      img.onload = () => {
        ctx.drawImage(img, 0, 0, img.width, img.height);
        ctx.setFontSize(20);
        ctx.setFillStyle('rgba(255, 255, 255, 0.7)');
        ctx.fillText(formattedDate, 10, img.height - 30);
        wx.canvasToTempFilePath({
          canvasId: 'myCanvasId',
          success: (res) => {
            this.setData({
              photosfzBack: res.tempFilePath,
            });
          },
        });
      };
    } else {
      console.error('全局画布变量未初始化成功。');
    }
  },
回答关注问题邀请回答
收藏

1 个回答

  • 正好时光
    正好时光
    10-18

    根据注释自己修改一下

    WXML:
    <canvas canvas-id="watermarkCanvas" style="width: {{canvasWidth}}px; height: {{canvasHeight}}px;"></canvas>
    <button bindtap="addWatermark">选择图片并添加水印</button>
    js:
    data: {
      canvasWidth0,
     canvasHeight0
    },
    addWatermark() {
        // 是否清空页面上的视觉效果
        // this.setData({
        //   canvasWidth: 0,
        //   canvasHeight: 0
        // });
        wx.chooseMedia({
          count1,
          mediaType: ['image'],
          sourceType: ['album''camera'],
          success(res) => {
            const tempFilePath = res.tempFiles[0].tempFilePath;
            
            wx.getImageInfo({
              src: tempFilePath,
              success(imageInfo) => {
                // 获取屏幕宽度
                const systemInfo = wx.getSystemInfoSync();
                const screenWidth = systemInfo.screenWidth;
                
                // 计算图片在canvas中的大小,保持原始宽高比
                const scale = screenWidth / imageInfo.width;
                const canvasWidth = screenWidth;
                const canvasHeight = imageInfo.height * scale;
    
    
                // 更新 canvas 尺寸
                this.setData({
                  canvasWidth: canvasWidth,
                  canvasHeight: canvasHeight
                }, () => {
                  // 在 setData 回调中创建 canvas 上下文,确保尺寸已更新
                  const ctx = wx.createCanvasContext('watermarkCanvas');
                  
                  // 清空 canvas
                  ctx.clearRect(00, canvasWidth, canvasHeight);
                  
                  // 绘制原图,铺满整个canvas
                  ctx.drawImage(tempFilePath, 00, canvasWidth, canvasHeight);
                  
                  // 设置水印样式
                  ctx.setFontSize(16);  // 固定字体大小为16px
                  ctx.setFillStyle('rgba(255, 255, 255, 0.5)');
                  ctx.setShadow(222'rgba(0, 0, 0, 0.5)');
                  ctx.rotate(-Math.PI / 6);
    
    
                  // 添加水印文字
                  const watermarkText = '我的水印';
                  const textWidth = ctx.measureText(watermarkText).width;
                  const xGap = textWidth * 2;  // 增加横向间距
                  const yGap = 48;  // 增加纵向间距
    
    
                  // 确保水印覆盖整个canvas,包括旋转后的边角
                  const diagonal = Math.sqrt(canvasWidth * canvasWidth + canvasHeight * canvasHeight);
                  for (let y = -diagonal; y < diagonal * 2; y += yGap) {
                    const rowOffset = ((y / yGap) % 2) * (xGap / 2);  // 偶数行错开半个宽度
                    for (let x = -diagonal - rowOffset; x < diagonal * 2; x += xGap) {
                      ctx.fillText(watermarkText, x, y);
                    }
                  }
                  
                  ctx.draw(false, () => {
                    wx.canvasToTempFilePath({
                      canvasId'watermarkCanvas',
                      success(res) => {
                        const watermarkedImagePath = res.tempFilePath;
                        // 上传图片的方法
                        this.uploadImage(watermarkedImagePath);
                      },
                      fail(error) => {
                        console.error('Canvas to image failed:', error);
                      }
                    });
                  });
                });
              },
              fail(error) => {
                console.error('Get image info failed:', error);
              }
            });
          },
          fail(error) => {
            console.error('Choose media failed:', error);
          }
        });
      },
    
    10-18
    有用
    回复 2
登录 后发表内容