渲染 HTML 元素到 canvas.toDataURL()
创建图像。我收到此错误:未捕获
SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
crossorigin
属性设置为
anonymous
,我已经这样做了,但没有效果。我在几个地方读过,包括
这篇文章,我需要在图像上设置标题。由于它来自 JS 中的new Image()
,我可以安全地为整个网站设置这些标头吗?即使我可以,它能解决问题吗?我的代码的相关部分:
function renderHtmlToCanvas(canvas, html) {
const ctx = canvas.getContext('2d');
const svg = `
<svg xmlns="http://www.w3.org/2000/svg" width="${canvas.width}" height="${canvas.height}">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml">${html}</div>
</foreignObject>
</svg>`;
const svgBlob = new Blob([svg], { type: 'image/svg+xml;charset=utf-8' });
const svgObjectUrl = URL.createObjectURL(svgBlob);
const tempImage = new Image();
tempImage.crossOrigin = 'anonymous';
tempImage.addEventListener('load', () => {
ctx.drawImage(tempImage, 0, 0);
canvasToImage(canvas);
URL.revokeObjectURL(svgObjectUrl);
});
tempImage.src = svgObjectUrl;
}
// Convert the canvas to an image
function canvasToImage(canvas) {
const image = new Image();
const screenshotData = canvas.toDataURL('image/webp');
}
renderHtmlToCanvas(canvas, html);
// This function takes any DOMDocumentElement as a first parameter.
// And return a Data URL of its generated image.
function RenderElement ( Element )
{
// Take the measures of the given Element.
const Measures = Element.getBoundingClientRect();
// The canvas does not need to exist in your document body.
const CanvasElement = document.createElement('canvas');
{
// The canvas is adjusted here.
CanvasElement.width = Measures.width;
CanvasElement.height = Measures.height;
}
const Context = CanvasElement.getContext('2d');
// Slightly changed SVG...
const ImageSVG =
`
<svg xmlns="http://www.w3.org/2000/svg" width="${CanvasElement.width}" height="${CanvasElement.height}">
<!-- YOU SHOULD INCLUDE ALL CSS RULES DIRECTLY HERE -->
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml">
${Element.outerHTML}
</div>
</foreignObject>
</svg>
`;
// The image also does not need to exist in your document body.
const ImageElement = document.createElement('img');
{
// The svg image source is already converted to Data URL (Base64).
ImageElement.src = `data:image/svg+xml;base64,${btoa(ImageSVG)}`;
}
Context.drawImage(ImageElement, 0, 0);
// Get the Data URL directly from the virtual canvas.
const ImageSRC = CanvasElement.toDataURL('image/webp');
return ImageSRC;
}
// Just creating a new image with the Generated image of the element.
const NewImg = document.createElement('img');
{
NewImg.src = RenderElement(document.getElementById('MyContent'));
}
// Appending the NewImg to the document.
document.body.appendChild(NewImg);
// Logging the NewImg.src to the console
console.log(NewImg.src);
<div id="MyContent">
<button>I do nothing</button>
<div>Hello World!</div>
</div>
<hr />
<div>
Generated image of what is above the hr above is shown below horizontal ruler below:
</div>
<hr />
运行该代码片段以查看其实际效果。如果第一次
Run
单击不起作用,请再次单击。
重要: 此函数不会将任何 CSS 导入到 SVG 中,这实际上会重新渲染您的元素。因此,您必须确保 CSS 规则加载到您的 SVG 内容中。