2017-09-27 18 views
-1

我有一个HTML代码如下:如何追加在“画布”的形象变成了“IMG”元素

<canvas id="canvas1" width="200" height="200"></canvas> 

和JavaScript代码如下:

var can = document.getElementById('canvas1'); 
var ctx = can.getContext('2d'); 
var src="https://vignette2.wikia.nocookie.net/mint524/images/d/d7/Sky.jpg/revision/latest?cb=20160706152654.jpg" 

var image = new Image(); 
image.onload = function(){ 
    ctx.drawImage(image,0,0,50,50); 
} 
ctx.fillRect(50,50,50,50); 
image.src = src 

var img = new Image(); 
img.src = can.toDataURL(); 
document.body.appendChild(img); 

我想转换canvasimg元素,但我发现我无法在canvas中将图像追加到img元素。 Detialed代码在here。 任何人都可以提供一些建议吗?

+0

的[腐坏画布不得出口]可能的复制(https://stackoverflow.com/questions/22710627/tainted-canvases-may-not-be-exported) – Halim

回答

-2

出于安全原因,您的本地驱动器被声明为“其他域”,并会污染画布。

(这是因为你最敏感的信息可能在你的本地驱动器!)。

测试时尝试这些替代方法:

  • 包装与超时的IMG出口从帆布
  • 把所有页面相关的文件格式(.html,.jpg和.js文件,的CSS等)上的 桌面(不在子文件夹中)。
  • 将您的图片发布到支持跨域共享的网站(如 dropbox.com)。确保你把你的图片在投寄箱的公用文件夹 和下载图像时也设置了跨原点标志(VAR IMG =新的图片(); img.crossOrigin =“匿名” ......)

setTimeout(
 
    function(){ 
 
    var can = document.getElementById('canvas1'); 
 
    var img = new Image(); 
 
    img.src = can.toDataURL(); 
 
    document.body.appendChild(img); 
 
},2000);

+1

记住以信贷[你使用的答案](https://stackoverflow.com/questions/22710627/tainted-canvases-may-not-be-exported)零件关闭。 SO上的所有内容均以[cc by-sa 3.0,需要署名]许可(https://creativecommons.org/licenses/by-sa/3.0/)。除了最后一点,你的答案的其他部分在这方面没有什么意义。 – K3N

+0

你是对的,最后一部分只是为了显示污染的IMG反应 – ShlomyN

1

如果你确保你的形象不被污染 - 看到这个问题,回答:Tainted canvases may not be exported,那么你就可以改变你的代码,以便您的旧图像加载后创建的新形象:

var can = document.getElementById('canvas1'); 
 
var ctx = can.getContext('2d'); 
 
var src = "//i.imgur.com/fHyEMsl.jpg"; 
 

 
var image = new Image(); 
 
image.crossOrigin = "anonymous"; 
 

 
image.onload = function() { 
 
    ctx.drawImage(image, 0, 0, 200, 200); 
 

 
    var img = new Image(); // move this into the onload of the image to make sure the canvas has been drawn 
 
    img.src = can.toDataURL("image/png"); 
 
    document.body.appendChild(img); 
 
} 
 
image.src = src;
<p>Canvas:</p> 
 
<canvas id="canvas1" width="200" height="200"></canvas> 
 
<p>Image should appear below:</p>

+0

好,它的工作原理。谢谢。 – user8627119

+0

你好,我遇到另一个问题,当我使用高分辨率的图像,而不是小图像。它显示错误:“No'Access-Control-Allow-Origin'标题出现在请求的资源上。”如何解决它?看到我的新代码在这里:https://jsfiddle.net/AndrewGong/mkx7f8un/9/ – user8627119

0

画布作用非常相似的图像。

当您使用canvas.toDataURL并将其分配给image.src时,您正在浪费大量内存。图像将从dataURL中解码,并使用与画布相同数量的像素RAM,但dataURL也将保留在内存中。

Base64编码不是为了紧凑而设计的。每个Base64字符编码6位,但每个Javascript字符使用16位。这使得dataURL比存储在磁盘上的数据量大2.667倍,并且在某些极端情况下可以大于原始像素数据。

您可以使用canvas.toBlob()并从blob构建图像,避免重复数据库URL的内存开销。但是,您仍然留下了编织图像的编织问题。

最简单的解决方案是将画布视为图像。像将图像添加到DOM一样,并且可以节省尝试编码和解码图像格式的麻烦。你想从画布不会做的图像中得到什么? src?那么这就是问题所在。

const canvas = document.createElement("canvas"); 
 
const ctx = canvas.getContext("2d"); 
 
ctx.fillRect(0,0,300,150); 
 
ctx.fillStyle = "white"; 
 
ctx.fillRect(10,10,280,130); 
 
ctx.fillStyle = "Blue"; 
 
ctx.fillRect(15,15,270,120); 
 
ctx.fillStyle = "white"; 
 
ctx.font = "28px arial"; 
 
ctx.fillText("Look like an Image", 20, 40); 
 
ctx.fillText("Acts like an Image", 20, 70); 
 
ctx.font = "20px arial"; 
 
ctx.fillText("Who cares if it's a Canvas", 20, 100); 
 
ctx.textAlign = "right"; 
 
ctx.fillText("", 270, 125); 
 

 

 
function copyCanvas(canvas){ 
 
    const c = canvas.cloneNode(); 
 
    c.getContext("2d").drawImage(canvas,0,0); 
 
    return c; 
 
} 
 
document.body.appendChild(copyCanvas(canvas));