首页 > 解决方案 > 如何自动下载画布图像?

问题描述

我正在开发一个小卡片创建器。它背后的想法是从 CSV 中获取数据,相应地从文件夹中获取一些图像,将它们与相关文本(名称、权力、奖金等)一起放入画布中,然后将其保存为图像(如果文件名会很棒= 卡名.jpg)。但我实际上坚持让下载正常工作。主要问题是我尝试的每个解决方案都给我一个空白的 jpeg,没有我填充的画布的痕迹。第二个问题是我不希望下载事件被按钮触发。只需选择 CSV,上传它,让代码为每张卡片创建一个画布,然后将每张卡片下载到同一文件夹中,无需任何确认。可能吗?

CSV 结构很简单,只有很多具有相同模式的行:ClanName,CardName,1,1,1,CardPower,CardBonus,FullName

Papaparse 库由我从他们的网站获得的两个文件处理,因为我没有找到任何 CDN。

我是初学者,所以答案越简单越好。重要的一点是将每个 img 保存为同一文件夹中的 jpg。(例如:C:\Users\MyName\Desktop\CardCollectionFolder)

该代码旨在运行一次,只是为了将大量卡片创建为 jpeg、离线和在我自己的计算机上。因此,内部没有安全问题。

这是我的代码(HTML/CSS + JS/JQuery)

$( document ).ready(function() {

  function 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) {
            callback(images);
          }
        };
        images[src].src = sources[src];
      }

    }

    function creaCartaFinale(results, i){
        

      var canvas = document.getElementById("myCanvas"+i);
      var context = canvas.getContext('2d');
      
        var clan=(results.data[i][0]);
        const nome =(results.data[i][1]); 
        var rarita =(results.data[i][2]);
        var stelle =(results.data[i][3]);
        var potenza =(results.data[i][4]);
        var danno =(results.data[i][5]);
        const potere =(results.data[i][6]);
        const bonus=(results.data[i][7]);
        var nomeintero=(results.data[i][8]);
    
        imgStelle = "Immagini/LivelloCarte/livello"+ stelle +".png";
        imgClan= "Immagini/IconeClan/"+ clan +"_42.png";
        if (rarita=="Non comune"){
            imgRarita = "Immagini/RaritaCarta/raritanoncomune.png";
        } else {
            imgRarita = "Immagini/RaritaCarta/rarita"+rarita+".png";
        }
    
        immagine ="Immagini/ImmaginiChar/"+clan+"_"+nomeintero+"_N"+stelle+"_HD_673.png"
    
        var sources = {
            image1: 'Immagini/SfondoCarte/base.png',
            image2:'Immagini/SfondoCarte/riquadro.png',
            image3: immagine,
            image4:'Immagini/SfondoCarte/poteri.png',
            image5: imgRarita,
            image6: imgStelle,
            image7: 'Immagini/SfondoCarte/riquadrobis.png',
            image8: imgClan,
            image9: 'Immagini/Numeri/'+potenza+'.png',
            image10:'Immagini/Numeri/'+danno+'.png',
          };
    
        
          loadImages(sources, function(images) {
            context.drawImage(images.image1, 0, 0,  2220 , 3240);  //SFONDO *   x - y
            context.drawImage(images.image2, 80, 80,  2040 ,1900);//RIQUADRO
            context.drawImage(images.image3, 0, 0,  2220 ,3150);  //IMMAGINE *
            context.drawImage(images.image4, 80, 2000,  2050 ,1150);  //LAYOUT POTERI *
            context.drawImage(images.image5, 520, 80,  1610 ,200);   //RARITA *
            context.drawImage(images.image6, 600, 2000,  1240 ,260);  //STELLE *
            context.drawImage(images.image7, 100, 70,  360 ,360);  //RIQUADRO CLAN *
            context.drawImage(images.image8, 120, 80,  320 ,320);  //CLAN *
            context.drawImage(images.image9, 170, 2350,  130 ,170);  //FORZA *
            context.drawImage(images.image10, 170, 2950,  130 ,170);  //DANNO *
    
            //STAMPA NOME
            context.font = "200px Calibri";
            var gradient = context.createLinearGradient (0,0, canvas.width,0)
            gradient.addColorStop("0", "white")
            context.fillStyle = gradient;
            context.fillText(nome, 600, 250);
    
    
            //STAMPA POTERI E BONUS
            context.font = "105px Calibri";
            if (potere.length > 34){
              var ultimoIndice = potere.length -1;
              var frase30 = potere.slice(0,33);
              var n = frase30.lastIndexOf(" ");
              var primaFrase = potere.slice(0,n)
              var secondaFrase = potere.slice(n,ultimoIndice)
              context.fillText(primaFrase, 750, 2500);
              context.fillText(secondaFrase, 750, 2620);
    
            }
            else{
               context.fillText(potere, 750, 2500);
            }
            if (bonus.length > 34){
              var ultimoIndice = bonus.length -1;
              var frase30 = bonus.slice(0,33);
              var n = frase30.lastIndexOf(" ");
              var primaFrase = bonus.slice(0,n)
              var secondaFrase = bonus.slice(n,ultimoIndice)
              context.fillText(primaFrase, 750, 2850);
              context.fillText(secondaFrase, 750, 2970);
            }
            else{
              context.fillText(bonus,750, 2850);
            }
    
          });
    }


  document.getElementById('txtFileUpload').addEventListener('change', upload, false);
  
  function upload(evt) {
      var file = evt.target.files[0];
      var reader = new FileReader();
      reader.readAsText(file);
      reader.onload = function (event) {
          var csvData = event.target.result;
          Papa.parse(csvData, {
              complete: function (results) {
                  console.log(results.data);
                  var numeroCarte=(results.data.length);
                  for(var i=0; i<numeroCarte; i++){
                    $( ".cartaSingola" ).prepend( "<canvas class='cardCanvas' id='myCanvas"+i+"' width='2500' height='3500'></canvas>" );
                    creaCartaFinale(results,i);
                    download_image(i);
                  }
              }
          });
      };
  }

  //THIS FUNCTION DOES NOT WORK, JUST GIVES BACK A BLANK FILE
  function download_image(i){
    var canvas = document.getElementById("myCanvas"+i);
    image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
    var link = document.createElement('a');
    link.download = "my-image.png";
    link.href = image;
    link.click();
  }
      

});
/* .contenitoreCarte{
    height:88mm;
    width:63mm;
} */

.cartabase{
    margin:15px;
    height:88mm;
    width:63mm;
}

.nomeCarta{
    position: relative;
    top: -352px;
    right: -102px;
    width:45mm;
    height:6mm;
    text-align: center;
    z-index:1;
    
}

.nomeCarta p{
    text-align: center;
    width: 100%;
    left: -32px;
    position: relative;
}

.potereCarta{
    position: relative;
    top: -352px;
    right: -102px;
    width:45mm;
    height:6mm;
    text-align: center;
}
.potereCarta p{
    text-align: center;
    
    position: relative;
    bottom: -194px;
    width: 82%;
    left: -6px;
    word-wrap: break-word
}
.bonusCarta{
    position: relative;
    top: -352px;
    right: -102px;
    width:45mm;
    height:6mm;
    text-align: center;
}
.bonusCarta p{
    text-align: center;
    width: 82%;
    left: -6px;
    bottom: -195px;
    position: relative;
    word-wrap: break-word
}

.forzaCarta{
    position: relative;
    top: -352px;
    right: -102px;
    width:45mm;
    height:6mm;
    text-align: center;
}
.forzaCarta p{
    text-align: center;
    width: 100%;
    left: -148px;
    bottom: -119px;
    position: relative;
}

.dannoCarta{
    position: relative;
    top: -352px;
    right: -100px;
    width:45mm;
    height:6mm;
    text-align: center;
}
.dannoCarta p{
    text-align: center;
    width: 100%;
    left: -146px;
    bottom: -139px;
    position: relative;
}

.livelloCarta{
    /* width: 32mm; */
    width: 42mm; 
    height: 7mm;
    right: -36px;
    top: -166px;
    position: relative;
}

.clanCarta{
    height: 9mm;
    width: 9mm;
    right: -15px;
    top: -278px;
    position: relative;
    z-index: 1;
}

.raritaCarta{
    height: 6mm;
    width: 45mm;
    right: -35px;
    top: -296px;
    position: relative;
}

.baseCarta{
    height: 88mm;
    width: 63mm;
    right: -7px;
    top: -312px;
    position: relative;
    z-index: -99;
}
 .riquadroCarta{
    height: 50mm;
    width: 56mm;
    right: -14px;
    top: -473px;
    position: relative;
}

.poteriCarta{
    height: 32mm;
    width: 58mm;
    right: -12px;
    top: -470px;
    position: relative;
    z-index: -99;
}

.immaginiCarta{
    height: 92mm;
    width: 68mm;
    right: -3px;
    top: -642px;
    position: relative;
    z-index: 1;
}


.cardCanvas{
    position: relative;
    display: block;
}
<html>

  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />

    <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet"type="text/css" />

    <link rel="stylesheet" href="Pagina.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="Pagina.js"></script> 
    <script src="papaparse.js"></script> 
    <script src="papaparse.min.js"></script> 

    <title>Card maker</title>                             
  
  </head>


  <body>

    <input type="file" name="File Upload" id="txtFileUpload" accept=".csv" />

    <div class="cartaSingola">
       
    </div>

  </body>

</html>

标签: javascriptjqueryhtmlcanvasdownload

解决方案


考虑以下:

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

// draw cloud
context.beginPath();
context.moveTo(170, 80);
context.bezierCurveTo(130, 100, 130, 150, 230, 150);
context.bezierCurveTo(250, 180, 320, 180, 340, 150);
context.bezierCurveTo(420, 150, 420, 120, 390, 100);
context.bezierCurveTo(430, 40, 370, 30, 340, 50);
context.bezierCurveTo(320, 5, 250, 20, 250, 50);
context.bezierCurveTo(200, 5, 150, 20, 170, 80);
context.closePath();
context.lineWidth = 5;
context.fillStyle = '#8ED6FF';
context.fill();
context.strokeStyle = '#0000ff';
context.stroke();

function download_image(trg) {
  var canvas = document.getElementById(trg);
  var dataUrl = canvas.toDataURL("image/png");
  var link = document.createElement('a');
  link.download = "my-image.png";
  link.href = dataUrl.replace("image/png", "image/octet-stream");
  console.log(link);
  link.click();
}

download_image("myCanvas");
<canvas id="myCanvas" width="578" height="200" style="display:none;"></canvas>

无法使用您的代码为您测试。


推荐阅读