我想获得图像的逐像素颜色数据,以便我可以将其调整为"8位";有点像用彩色方块组成的网格。
从我目前所做的研究来看,获得这种数据的标准方法似乎是使用HTML5画布和上下文。getImageData(例子)。到目前为止,虽然我还没有幸运地在React应用程序中工作。
我得到的最接近的是这个。我确定它有很多错误,可能与我与DOM交互的方式有关,但它至少返回了一个imageData对象。问题是每个像素的颜色值都是0。
更新使用ref代替getElementById
function App() {
const imgRef = useRef(null);
const img = <img ref={imgRef} src={headshot} />;
// presumably we want to wait until after render?
useEffect(() => {
if (imgRef === null) {
console.log("image ref missing");
return;
}
if (imgRef.current === null) {
console.log("image ref is null");
return;
}
// couldn't use imgRef.current.offsetHeight/Width for these because typscript
// thinks imgRef.current is `never`?
const height = 514;
const width = 514;
const canvas = document.createElement('canvas');
canvas.height = height; canvas.width = width;
const context = canvas.getContext && canvas.getContext('2d');
if (context === null) {
console.log(`context or image missing`);
return
}
context.drawImage(imgRef.current, 0, 0);
const imageData = context.getImageData(0, 0, width, height);
console.log(`Image Data`, imageData);
}, []);
return img;
}
相关:最终我想在不实际显示图像的情况下获得这些数据,因此任何关于这方面的提示也将受到赞赏。
谢谢!
您没有等待图像加载。(与常规HTML一样,这是异步发生的。)
因此,与其使用组件安装后立即运行的效果,不如将其连接到图像的onLoad
。除此之外:
- 不需要检查
imgRef
是否为空;ref box本身从来不是。 - 当使用TypeScript和DOM ref时,使用
useRef<HTML...Element>(null);
使ref.current
具有正确的类型。 - 没有必要让
imgRef.current
成为处理器的依赖项,因为refs的改变不会导致组件更新。
export default function App() {
const imgRef = React.useRef<HTMLImageElement>(null);
const readImageData = React.useCallback(() => {
const img = imgRef.current;
if (!img?.width) {
return;
}
const { width, height } = img;
const canvas = document.createElement("canvas");
canvas.height = height;
canvas.width = width;
const context = canvas.getContext?.("2d");
if (context === null) {
return;
}
context.drawImage(img, 0, 0);
const imageData = context.getImageData(0, 0, width, height);
console.log(`Image Data`, imageData);
}, []);
return <img ref={imgRef} src={kitten} onLoad={readImageData} />;
}
<标题>编辑你知道我现在如何做到这一点,而不实际显示图像吗?
要在DOM中读取图像而不实际显示它,您需要new Image
-然后可以使用效果。
/** Promisified image loading. */
function loadImage(src: string): Promise<HTMLImageElement> {
return new Promise((resolve, reject) => {
const img = new Image();
img.addEventListener("load", () => {
resolve(img);
});
img.addEventListener("error", reject);
img.src = src;
});
}
function analyzeImage(img: HTMLImageElement) {
const { width, height } = img;
const canvas = document.createElement("canvas");
canvas.height = height;
canvas.width = width;
const context = canvas.getContext?.("2d");
if (context === null) {
return;
}
context.drawImage(img, 0, 0);
const imageData = context.getImageData(0, 0, width, height);
console.log(`Image Data`, imageData);
}
export default function App() {
React.useEffect(() => {
loadImage(kitten).then(analyzeImage);
}, []);
return <>hi</>;
}
标题>