[英]useRef always coming back as null and is not able to get .current value in image comparison
I am trying to make a react component to compare two images using the pixel match library and I am stuck on the output image.我正在尝试制作一个反应组件来使用像素匹配库比较两个图像,但我卡在了 output 图像上。 The outputCanvasRef is always null so in the
compareImages
function it errors on the line with outputCanvas.width = image1.width;
outputCanvasRef 始终为 null,因此在
compareImages
function 中,它在outputCanvas.width = image1.width;
import { useRef, useState } from "react";
import pixelmatch from "pixelmatch";
const Tab1 = () => {
const [image1, setImage1] = useState(null);
const [image2, setImage2] = useState(null);
const [difference, setDifference] = useState(null);
const canvas1Ref = useRef(null);
const canvas2Ref = useRef(null);
const outputCanvasRef = useRef(null);
const handleFileChange = (setImage) => (event) => {
const file = event.target.files[0];
const fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = () => {
const image = new Image();
image.src = fileReader.result;
image.onload = () => setImage(image);
};
};
const compareImages = async () => {
if (image1 && image2) {
const canvas1 = canvas1Ref.current;
const canvas2 = canvas2Ref.current;
const outputCanvas = outputCanvasRef.current;
canvas1.width = image1.width;
canvas1.height = image1.height;
canvas2.width = image2.width;
canvas2.height = image2.height;
outputCanvas.width = image1.width;
outputCanvas.height = image1.height;
const ctx1 = canvas1.getContext("2d");
const ctx2 = canvas2.getContext("2d");
const outputCtx = outputCanvas.getContext("2d");
outputCtx.scale(0.5, 0.5);
ctx1.drawImage(image1, 0, 0);
ctx2.drawImage(image2, 0, 0);
const diff = pixelmatch(
ctx1.getImageData(0, 0, image1.width, image1.height),
ctx2.getImageData(0, 0, image2.width, image2.height),
null,
image1.width,
image1.height
);
outputCtx.putImageData(diff, 0, 0);
setDifference(outputCanvas);
}
};
return (
<div>
<input type="file" onChange={handleFileChange(setImage1)} />
<input type="file" onChange={handleFileChange(setImage2)} />
<button onClick={() => { compareImages() }}>Compare Images</button>
<canvas ref={canvas1Ref} />
<canvas ref={canvas2Ref} />
{difference && <canvas ref={outputCanvasRef} />}
</div>
);
}
export default Tab1;
Can use the spread operator like this {...props}
to pass a conditional ref可以使用像这样的扩展运算符
{...props}
来传递条件引用
const itemProps = difference ? { ref: outputCanvasRef } : {};
<canvas {...itemProps} />
There are several things that went wrong in your implementation:您的实施中有几处错误:
output canvas
without any condition so that it is always available for use in the comparison function.output canvas
,以便它始终可用于比较 function。pixelmatch
package requires that the images you want to compare always have the same width & height. pixelmatch
package 要求您要比较的图像始终具有相同的宽度和高度。 To do this, you can use the width & height of the first image for both image 1 & image 2 canvas.getImageData
call to the pixelmatch
.getImageData
调用返回的数组缓冲区传递给pixelmatch
。 The getImageData
returns ImageData
object. You can access the array buffer like this ImageData.data
getImageData
返回ImageData
object。您可以像这样访问数组缓冲区ImageData.data
ImageData
object's data
field to the pixelmatch
library's third parameter as argument so that the difference in pixels can be written in the ImageData
object.ImageData
对象的data
字段作为参数传递给pixelmatch
库的第三个参数,以便可以将像素差异写入ImageData
object。
import { useRef, useState } from "react";
import pixelmatch from "pixelmatch";
const Tab1 = () => {
const [image1, setImage1] = useState(null);
const [image2, setImage2] = useState(null);
const [difference, setDifference] = useState(null);
const canvas1Ref = useRef(null);
const canvas2Ref = useRef(null);
const outputCanvasRef = useRef(null);
const handleFileChange = (setImage) => (event) => {
const file = event.target.files[0];
const fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = () => {
const image = new Image();
image.src = fileReader.result;
image.onload = () => setImage(image);
};
};
const compareImages = async () => {
if (image1 && image2) {
const canvas1 = canvas1Ref.current;
const canvas2 = canvas2Ref.current;
const outputCanvas = outputCanvasRef.current;
canvas1.width = image1.width;
canvas1.height = image1.height;
canvas2.width = image1.width;
canvas2.height = image1.height;
outputCanvas.width = image1.width;
outputCanvas.height = image1.height;
const ctx1 = canvas1.getContext("2d");
const ctx2 = canvas2.getContext("2d");
const outputCtx = outputCanvas.getContext("2d");
const diff = outputCtx.createImageData(image1.width, image1.height);
ctx1.drawImage(image1, 0, 0);
ctx2.drawImage(image2, 0, 0);
pixelmatch(
ctx1.getImageData(0, 0, image1.width, image1.height).data,
ctx2.getImageData(0, 0, image1.width, image1.height).data,
diff.data,
image1.width,
image1.height
);
outputCtx.putImageData(diff, 0, 0);
setDifference(diff);
}
};
return (
<div>
<input type="file" onChange={handleFileChange(setImage1)} />
<input type="file" onChange={handleFileChange(setImage2)} />
<button onClick={() => { compareImages() }}>Compare Images</button>
<canvas ref={canvas1Ref} />
<canvas ref={canvas2Ref} />
{<canvas ref={outputCanvasRef} />}
</div>
);
}
export default Tab1;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.