我在使用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);
},
})
},
})
})
},
引用 皆我百晓生 小程序回复内容作答:
根据你提供的代码,有几个可能导致图片没有成功显示的问题:
在canvas绘制之前,未等待画布渲染完毕。在async函数中,canvas的绘制是一个异步操作,因此需要等待画布渲染完毕之后再进行下一步操作。你可以尝试在canvas.draw()
之后使用await
关键字等待画布渲染完毕,然后再执行后续操作。
在uni.canvasPutImageData
方法中,你传递了res.data
作为参数,而正确的应该是grayImageData
,因为你修改了像素数据保存到了grayImageData
中。
你在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);
}
);
});
},
})
},
})
})
}
请尝试根据这个修改后的代码运行,看看问题是否得到解决。如果还有问题,请提供更多信息。