qq_33419134 2023-09-14 15:10 采纳率: 50%
浏览 77

uniapp 使用canvas画图时,图片没有成功显示

我在使用uniapp开发时遇到了一个问题
我的开发步骤是
1:传入下面方法中一张图片,然后使用uni.getImageInfo获取图片宽高等信息,并将这张图片写入名为signCanvas的画布中
2:接着使用uni.canvasGetImageData方法读取signCanvas画布的图片像素数据,紧接着通过循环方式将符合条件的像素改变颜色,并将新的像素数据保存到grayImageData中
3:接着在使用uni.canvasPutImageData方法将新的像素数据重新写入signCanvas画布中,最后结束

但是我遇到问题了,代码跑完后,新的像素数据总是很随机,有时候显示的是原来的图片,有时候显示的又确实是新的像素图片,就很随机,也没有发现问题出在哪里。

麻烦大家帮我看看呗,怎么优化和修改

<template>
    <view>
        <image v-if="imageSrc" :src="imageSrc" :style="{width: width + 'px',height: height + 'px'}"></image>
        <view>1</view>
        <canvas canvas-id="signCanvas" :style="{width: width + 'px',height: height + 'px'}"></canvas>
    </view> 
</template>



async processImage(tempFilePath) {
              return new Promise((resolve, reject) => {
                this.imageSrc = tempFilePath;//裁剪的图片
                uni.getImageInfo({
                    src: tempFilePath,
                    success: async (imageInfo) => {
                        this.height = imageInfo.height;
                        this.width = imageInfo.width;
                        const canvas = uni.createCanvasContext('signCanvas',this);
                        canvas.clearRect(0, 0, imageInfo.width, imageInfo.height)
                        canvas.drawImage(imageInfo.path, 0, 0, imageInfo.width, imageInfo.height);
                        //canvas.draw(true);
                        //await sleep(2000);
                        console.log("112")
                        //await this.sleep(200) // 某些平台 canvas 渲染慢,需要等待
                        uni.canvasGetImageData({
                          canvasId: 'signCanvas',
                          x: 0,
                          y: 0,
                          width: imageInfo.width,
                          height: imageInfo.height,
                          success: async (res) => {
                            console.log("canvasGetImageData",res)
                            const data = res.data;
                            const grayImageData = res.data;//灰度图数据 */
                            let grayValue = 0; // 灰度值范围为0-255  
                            let greenPixels = 0;
                            for (let i = 0; i < data.length; i += 4) {
                              const red = data[i];
                              const green = data[i + 1];
                              const blue = data[i + 2];
                              let hsv = this.rgbToHsb(red,green,blue);
                                if (hsv[0] >= 0.075 && hsv[1] >= 0.15 &&
                                        hsv[2] > 0.1389 && hsv[2] <= 0.4444) {
                                    greenPixels++;
                                }else{
                                    grayValue = Math.floor(data[i] * 0.114 + data[i + 1] * 0.587 + data[i + 2] * 0.299);//根据RGB值计算灰度值
                                    grayImageData[i] = 255; // 将灰度值存储到数组中对应位置的R值
                                    grayImageData[i + 1] = 255; // 将灰度值存储到数组中对应位置的G值
                                    grayImageData[i + 2] = 255; // 将灰度值存储到数组中对应位置的B值
                                    grayImageData[i + 3] = data[i + 3]; // 保留原始图片的透明度值
                                }
                            }
                            console.log("canvasGetImageData11111",grayImageData)
                            //await this.sleep(2000) // 某些平台 canvas 渲染慢,需要等待
                            canvas.draw();
                            
                            uni.canvasPutImageData(
                            {
                                canvasId: "signCanvas",
                                x: 0,
                                y: 0,
                                width: imageInfo.width,
                                data: res.data,
                            },
                            false,
                            );
                            resolve(grayImageData);
                          },
                        })
                    },
                })
              })
            },
  • 写回答

1条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2023-09-14 16:29
    关注

    引用 皆我百晓生 小程序回复内容作答:
    根据你提供的代码,有几个可能导致图片没有成功显示的问题:

    1. 在canvas绘制之前,未等待画布渲染完毕。在async函数中,canvas的绘制是一个异步操作,因此需要等待画布渲染完毕之后再进行下一步操作。你可以尝试在canvas.draw()之后使用await关键字等待画布渲染完毕,然后再执行后续操作。

    2. uni.canvasPutImageData方法中,你传递了res.data作为参数,而正确的应该是grayImageData,因为你修改了像素数据保存到了grayImageData中。

    3. 你在uni.canvasPutImageData方法中的第二个参数设置为了false,这表示将使用原始像素覆盖画布。如果你想要完全替换画布中的像素数据,可以将第二个参数设置为true

    我稍作修改的代码如下:

    async processImage(tempFilePath) {
      return new Promise((resolve, reject) => {
        this.imageSrc = tempFilePath; //裁剪的图片
        uni.getImageInfo({
          src: tempFilePath,
          success: async (imageInfo) => {
            this.height = imageInfo.height;
            this.width = imageInfo.width;
            const canvas = uni.createCanvasContext('signCanvas', this);
            canvas.clearRect(0, 0, imageInfo.width, imageInfo.height)
            canvas.drawImage(imageInfo.path, 0, 0, imageInfo.width, imageInfo.height);
            //canvas.draw(true);
            //await sleep(2000);
            console.log("112")
            //await this.sleep(200) // 某些平台 canvas 渲染慢,需要等待
            uni.canvasGetImageData({
              canvasId: 'signCanvas',
              x: 0,
              y: 0,
              width: imageInfo.width,
              height: imageInfo.height,
              success: async (res) => {
                console.log("canvasGetImageData", res)
                const data = res.data;
                const grayImageData = new Uint8ClampedArray(data.length); // 创建一个与原始像素数据相同大小的数组
                let grayValue = 0; // 灰度值范围为0-255  
                let greenPixels = 0;
                for (let i = 0; i < data.length; i += 4) {
                  const red = data[i];
                  const green = data[i + 1];
                  const blue = data[i + 2];
                  let hsv = this.rgbToHsb(red, green, blue);
                  if (hsv[0] >= 0.075 && hsv[1] >= 0.15 &&
                    hsv[2] > 0.1389 && hsv[2] <= 0.4444) {
                    greenPixels++;
                  } else {
                    grayValue = Math.floor(data[i] * 0.114 + data[i + 1] * 0.587 + data[i + 2] * 0.299); //根据RGB值计算灰度值
                    grayImageData[i] = 255; // 将灰度值存储到数组中对应位置的R值
                    grayImageData[i + 1] = 255; // 将灰度值存储到数组中对应位置的G值
                    grayImageData[i + 2] = 255; // 将灰度值存储到数组中对应位置的B值
                    grayImageData[i + 3] = data[i + 3]; // 保留原始图片的透明度值
                  }
                }
                console.log("canvasGetImageData11111", grayImageData)
                //await this.sleep(2000) // 某些平台 canvas 渲染慢,需要等待
                canvas.draw(false, async () => {
                  uni.canvasPutImageData(
                    {
                      canvasId: "signCanvas",
                      x: 0,
                      y: 0,
                      width: imageInfo.width,
                      data: grayImageData, // 传入修改后的像素数据
                    },
                    true,  // 替换整个画布像素数据
                    () => {
                      resolve(grayImageData);
                    }
                  );
                });
              },
            })
          },
        })
      })
    }
    

    请尝试根据这个修改后的代码运行,看看问题是否得到解决。如果还有问题,请提供更多信息。

    评论

报告相同问题?

问题事件

  • 创建了问题 9月14日

悬赏问题

  • ¥60 db2move nlzxams import 导出db2备份数据报错
  • ¥15 关于#python#的问题:全文总结功能咨询
  • ¥15 俄罗斯方块中无法同时消除多个满行
  • ¥15 c#转安卓 java html
  • ¥15 使用gojs3.0,如何在nodeDataArray设置好text的位置,再go.TextBlock alignment中进行相应的改变
  • ¥15 psfusion图像融合指标很低
  • ¥15 银河麒麟linux系统如何修改/etc/hosts权限为777
  • ¥50 医院HIS系统代码、逻辑学习
  • ¥30 docker离线安装mysql报错,如何解决?
  • ¥15 构建工单的总账影响在哪里查询或修改