绘制后如何下载不同的html画布?

Posted

技术标签:

【中文标题】绘制后如何下载不同的html画布?【英文标题】:How to download different html canvas after drawing on it? 【发布时间】:2021-12-13 20:17:38 【问题描述】:

我正在开发一个 nft-art-generator 应用程序,该应用程序会生成多个 不同 html 画布(作为图像)。 每个画布是 3 张图像的组合,也就是说,每个画布应该绘制 3 张图像,在画布上绘制后我下载它。

问题是当我检查下载的画布时,我得到了相同的画布。更准确地说,我得到最后生成的画布已被多次下载,就像之前生成的所有画布都消失了一样。

我认为这是因为我的代码中的某些内容正在异步运行。

这是我的 React.js 代码

const generateCollection = async()=>

//In this exemple i want to generate 2 canvas only!!
  for(var k = 1; k <= 2; k++)
    drawLayer(data, k)
   
  

  
const drawLayer = (data, index)=>
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d')
  let sources = ;
  //Get some random images url
  const objURLs = getImagesURLs(data, index);
  
  objURLs.forEach((url,i)=>
    const key = `image$i+1`;
    Object.assign(sources, [key]: url)
  )
  
  loadImages(sources, function(images) 
    objURLs.forEach((url,i)=>
      if (Boolean(url)) 
        context.drawImage(images[`image$i+1`], 0, 0, 230, 230)
      
    )
  );
  
  setTimeout(()=> download(canvas.current, index), 1000);
  


const loadImages = (sources, callback)=> 
  var images = ;
  var loadedImages = 0;
  var numImages = 0;
  // get num of sources
  for(var src in sources) 
    numImages++;
  
  for(var src in sources) 
    images[src] = new Image();
    images[src].onload = function() 
      if(++loadedImages >= numImages) 
        console.log("!!  ", images )
          callback(images);
      
    ;
    images[src].src = sources[src];
  


const download = (canvas, index)=>
  console.log("Download: ", canvas)
  var url = canvas.toDataURL("image/png");
  var link = document.createElement('a');
  link.download = `img_$index.png`;
  link.href = url;
  link.click();
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<canvas 
  id="myCanvas"
  ref=canvas
  width=230
  height=230
/>

<Button onClick=()=>generateCollection() ><Button>

这是一个基于

的现场演示代码

https://jsfiddle.net/vprdhomf/1/

I will appreciate any help, or suggestion!!

【问题讨论】:

(1) 加载图片是异步的,所以callback被异步调用。 (2) 如果所有画布组合在不到一秒的时间内完成,setTimeoutdownload 的调用只会看到画布处于其最终状态——要么等待每次下载,然后再创建下一个下载,要么使用多个画布元素. (3) 如果图片是跨域加载的,并且服务器不允许cross domain requests,canvas.toDataURL会抛出异常。因此,修复小提琴似乎是不可能的。 非常感谢,您的回答很明确,很有帮助!!。我所做的是在创建下一个下载之前等待每次下载。 setTimeout 函数在这种情况下没有用。 【参考方案1】:

解除问题评论:

    加载图片是异步的,所以callback被异步调用。

    如果在不到一秒的时间内完成了所有画布组合(不同组的多个图像),则对downloadsetTimeout 调用只会看到画布处于其最终状态。要解决此问题,您可以

    在创建下一个下载之前等待每个下载启动,或者 使用多个画布元素,或者也许 将每个画布组合的数据 URL 存储在一个数组中,以便以后下载。

    如果图像是跨域加载的,并且服务器不允许cross domain requests,canvas.toDataURL 会抛出security exception。因此,使用其中提供的 URL 修复小提琴变得不可能。

【讨论】:

以上是关于绘制后如何下载不同的html画布?的主要内容,如果未能解决你的问题,请参考以下文章

使用D3制作图表--画布绘制

画布旋转后如何检测画布上的点

千呼万唤 HTML 5 - 画布(canvas)之绘制图形

如何使用html5画布元素绘制透明图像

如何提高 HTML 画布绘制像素的性能

我们如何在 html5 画布上绘制调整大小的图像?