我正在通过以下在Sandbox托管的代码
import React, { useEffect, useRef } from "react";
import ReactDOM from "react-dom";
import backImg from "./background.png";
const Canvas = props => {
const canvas = useRef(null);
const image = useRef(null);
useEffect(() => {
const ctx = canvas.current.getContext("2d");
image.current.onload = () => {
ctx.drawImage(image.current, 0, 0);
ctx.font = "40px Courier";
ctx.fillText(props.text, 210, 75);
};
}, []);
useEffect(() => {
const ctx = canvas.current.getContext("2d");
ctx.drawImage(image.current, 0, 0);
ctx.font = "40px Courier";
ctx.fillText(props.text, 210, 75);
});
return (
<div>
<canvas ref={canvas} width={640} height={425} />
<img
ref={image}
alt="Stackoverflow56203352"
src={backImg}
className="hidden"
/>
</div>
);
};
function App() {
return (
<div className="App">
<Canvas text="TEST 123" />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
我不确定在图像上实现文本后如何提取图像URL。即,就我而言,我想要图像的URL带有文本。
我希望图像显示在材料 - UI的CardMedia组件中。
您可以使用htmlcanvaselement.todataurl((方法将画布导出到数据URL。
喜欢:
useEffect(() => {
const ctx = canvas.current.getContext("2d");
ctx.drawImage(image.current, 0, 0);
ctx.font = "40px Courier";
ctx.fillText(props.text, 210, 75);
const imgUrl = canvas.current.toDataURL("image/jpeg");
});
,但必须从相同的来源提供图像,否则您会遇到此错误(在沙箱中发生(:
Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
有关此错误的资源以及如何处理
下面有效的示例(我使用了Facebook托管的图像,因为他们据说支持这种事情,并在图像来自相同的来源,宽松的来源或具有该图像时消失了crossOrigin="anonymous"
属性,在新选项卡中打开控制台输出,以查看结果,如所请求的OP,在Marterialui的CardMedia中显示了结果:
const backImg = "https://scontent-cdg2-1.xx.fbcdn.net/v/t1.0-9/26907788_1614183255284072_4356465325754439623_n.jpg?_nc_cat=102&_nc_oc=AQle2ac8QeR7C5HY-Z9oxWXbMdzjkDlVo8WYfhqDZArSYoEb1q1Xv5ZaE1Z4JNm7bmY&_nc_ht=scontent-cdg2-1.xx&oh=1c12333fe33d7d3fc2e39d3794d7dab4&oe=5DC018D1";
const { CardMedia } = MaterialUI;
const Canvas = props => {
const [finalSrc, setFinalSrc] = React.useState(null)
const canvas = React.useRef(null);
const image = React.useRef(null);
React.useEffect(() => {
const ctx = canvas.current.getContext("2d");
image.current.onload = () => {
ctx.drawImage(image.current, 0, 0);
ctx.font = "40px Courier";
ctx.fillText(props.text, 210, 75);
};
}, []);
React.useEffect(() => {
const ctx = canvas.current.getContext("2d");
ctx.drawImage(image.current, 0, 0);
ctx.font = "40px Courier";
ctx.fillText(props.text, 210, 75);
setFinalSrc(canvas.current.toDataURL("image/jpeg"));
});
return (
<div>
{finalSrc && <CardMedia image={finalSrc} style={{ height: 425, width: 640 }} />}
<canvas ref={canvas} width={640} height={425} className="hidden" />
<img
ref={image}
alt="Stackoverflow56203352"
src={backImg}
className="hidden"
crossOrigin="anonymous"
/>
</div>
);
};
function App() {
return (
<div className="App">
<Canvas text="TEST 123" />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
.hidden {
visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js" crossorigin="anonymous"></script>
<div id="root"></div>