uni-app canvas 保存图片不一致问题

uni-app canvas 保存图片不一致问题

示例代码:

// 保存图片
uni.canvasToTempFilePath({
    canvasId: 'drawCanvas',
    destWidth: this.canvasWidth * this.pixelRatio,
    destHeight: this.canvasHeight * this.pixelRatio,
    success: (response) => {
        var imgCurrentPath = response.tempFilePath;
        editObj.imgUrl = imgCurrentPath
        that.$store.commit('setOneImgList', imgCurrentPath)
        uni.switchTab({
            url: '../index/index'
        })
    }
})

// 设置 canvas 的宽高
getImgInfo(imgUrl) {
    console.log('0')
    console.log(imgUrl)
    wx.getSystemInfo({
        success: (response) => {
            console.log(response);
            if (response.pixelRatio == 3) {
                this.pixelRatioWidth = 1130
            } else if (response.pixelRatio == 2) {
                this.pixelRatioWidth = 830
            }
            this.pixelRatio = response.pixelRatio;
            uni.getImageInfo({
                src: imgUrl,
                success: (res) => {   
                    this.canvasWidth = this.pixelRatioWidth / this.pixelRatio;
                    this.canvasHeight = (this.canvasWidth / res.width) * res.height;
                },
                fail: (err) => {
                    console.log('获取图片信息失败', err);
                }
            })
        }
    })
}

操作步骤:

// 撤销的代码
clearDrawBoard() {
    if (this.lastHollowRectList.length !== 0) {
        this.lastHollowRectList.pop()
    }
    var allDrawWorksPath = this.allDrawWorksPath;
    if (this.allDrawWorksPath == null || this.allDrawWorksPath.length == 0 || this.allDrawWorksPath == undefined) return
    var privWorksPath = this.allDrawWorksPath.pop();
    this.drawContext.setFillStyle(this.backgrounColor);
    this.getImage(privWorksPath)
    this.drawContext.drawImage(privWorksPath, 0, 0, this.canvasWidth, this.canvasHeight);
    this.drawContext.draw();
}

预期结果:

希望附件中的图片每次保存不变

实际结果:

附件中的图片每次保存会变大

bug描述:

使用 canvas 保存图片 和 撤销图片时 都会用到 uni.canvasToTempFilePath 这个方法,这个方法在保存的时候 在电脑上调试没有问题,手机上图片会放大一块

Image 1

Image 2

Image 3


更多关于uni-app canvas 保存图片不一致问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于uni-app canvas 保存图片不一致问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html


在使用 uni-app 开发时,如果你在 canvas 中绘制内容并保存为图片时,可能会遇到保存的图片与 canvas 上显示的内容不一致的问题。这个问题通常与以下几个方面有关:


1. Canvas 的 DPR(Device Pixel Ratio)问题

  • 原因:不同设备的 DPR(设备像素比)不同,导致 canvas 的绘制分辨率与实际显示的像素不一致。
  • 解决方法
    • 在绘制之前,手动设置 canvas 的宽度和高度,乘以 DPR,以确保绘制和保存时的分辨率一致。
    const dpr = uni.getSystemInfoSync().pixelRatio;
    const canvas = uni.createCanvasContext('myCanvas');
    canvas.width = canvasWidth * dpr;
    canvas.height = canvasHeight * dpr;
    canvas.scale(dpr, dpr); // 缩放画布
    
    • 保存图片时,确保使用正确的尺寸。

2. 异步绘制问题

  • 原因:如果 canvas 的绘制是异步的(例如加载网络图片),可能在绘制未完成时就调用了保存图片的方法。
  • 解决方法
    • 确保所有绘制操作完成后再调用保存图片的方法。可以使用 PromisesetTimeout 确保绘制完成。
    const drawImage = () => {
      return new Promise((resolve) => {
        const ctx = uni.createCanvasContext('myCanvas');
        ctx.drawImage('path/to/image', 0, 0, width, height, () => {
          ctx.draw(true, resolve);
        });
      });
    };
    
    drawImage().then(() => {
      uni.canvasToTempFilePath({
        canvasId: 'myCanvas',
        success: (res) => {
          console.log('图片保存成功', res.tempFilePath);
        }
      });
    });
    

3. Canvas 的绘制顺序问题

  • 原因canvas 的绘制是覆盖式的,如果绘制顺序不正确,可能会导致最终保存的图片与预期不一致。
  • 解决方法
    • 确保绘制顺序正确,先绘制背景,再绘制其他内容。
    • 使用 ctx.draw(true) 强制同步绘制。

4. Canvas 的尺寸与样式不一致

  • 原因canvaswidthheight 属性与 CSS 样式中的宽高不一致,导致绘制内容被拉伸或压缩。
  • 解决方法
    • 确保 canvaswidthheight 属性与 CSS 样式中的宽高一致。
    <canvas canvas-id="myCanvas" style="width: 300px; height: 200px;" />
    
    const ctx = uni.createCanvasContext('myCanvas');
    ctx.width = 300;
    ctx.height = 200;
    

5. Canvas 的绘制内容未同步

  • 原因uni-appcanvas 绘制是异步的,如果没有调用 ctx.draw(true),绘制内容可能不会立即生效。
  • 解决方法
    • 在绘制完成后,调用 ctx.draw(true) 强制同步绘制。
    const ctx = uni.createCanvasContext('myCanvas');
    ctx.fillRect(0, 0, 100, 100);
    ctx.draw(true); // 强制同步绘制
    

6. Canvas 的保存方法问题

  • 原因uni.canvasToTempFilePath 的参数配置不正确,导致保存的图片与 canvas 内容不一致。
  • 解决方法
    • 确保 uni.canvasToTempFilePath 的参数正确,例如 canvasIdwidthheight 等。
    uni.canvasToTempFilePath({
      canvasId: 'myCanvas',
      width: 300,
      height: 200,
      success: (res) => {
        console.log('图片保存成功', res.tempFilePath);
      }
    });
回到顶部