HTML5 Canvas到DataURL在for循环中始终相同

HTML5 Canvas toDataURL is always the same in a for loop

本文关键字:循环 for Canvas DataURL HTML5      更新时间:2023-09-26

考虑这个JSFiddle。在它中,我选择了一些照片,然后我想用画布对它们进行base64编码,这样我就可以将它们存储在sessionStorage中,以便延迟上传。因为我为多个文件设置了它,所以我循环浏览每个文件并创建一个图像和一个画布,但不管怎样,每次似乎都输出完全相同的base64编码图像。通过测试,我知道在每个循环迭代中,图像都是不同的,并且确实指向不同的文件blob,但画布只是一遍又一遍地输出相同的东西,我认为这也是文件列表中的最后一个文件。有时它也会输出一个"数据"字符串,就这样。如果有人能给我指明正确的方向,我会很高兴的。

代码如下:

HTML

<style type="text/css">
    input[type="file"] {
        display: none;
    }
    a {
        display: inline-block;
        margin: 6px;
    }
</style>
<form action="#" method="post">
    <input type="file" accept="image/*" multiple />
    <button type="button">Select Photos</button>
</form>
<nav></nav>

JavaScript

console.clear();
$(function () {
  $("button[type=button]").on("click", function (e) {
    $("input[type=file]").trigger("click");
  });
  
  $("input[type=file]").on("change", function (e) {
    var nav = $("nav").empty();
    
    for (var i = 0, l = this.files.length; i < l; i++) {
      var file = this.files[i],
          image = new Image();
          
      $(image).on("load", i, function (e) {
        var canvas = document.createElement("canvas"),
            context = canvas.getContext("2d");
        
      	canvas.height = this.height;
      	canvas.width = this.width;
      	
        context.drawImage(this, 0, 0);
        
        nav.append("<a href='"" + canvas.toDataURL("image/jpeg") + "'" target='"_blank'">" + e.data + "</a>");
        
        URL.revokeObjectURL(this.src);
      });
      
      image.src = URL.createObjectURL(file);
    }
  });
});

但不管怎样,它似乎只是输出完全相同的基数64每次编码图像。

.load()事件是异步的。您可以使用$.when()$.Deferred(),用$.map()代替for循环来处理异步加载的img元素。需要注意的是,所显示的a元素文本可能不是按数字顺序排列的;其可以通过对CCD_ 9处的元素进行排序来调整;尽管问题中没有提到,但如果需要,也可以实现图像的顺序列出或加载。

$("input[type=file]").on("change", function(e) {
    var nav = $("nav").empty();
    var file = this.files
    $.when.apply($, $.map(file, function(img, i) {    
      return new $.Deferred(function(dfd) {
        var image = new Image();
        $(image).on("load", i, function(e) {
          var canvas = document.createElement("canvas")
          , context = canvas.getContext("2d");   
          canvas.height = this.height;
          canvas.width = this.width;    
          context.drawImage(this, 0, 0);    
          nav.append("<a href='"" 
                    + canvas.toDataURL() 
                    + "'" target='"_blank'">" 
                    + e.data + "</a>");
          dfd.resolve()
          URL.revokeObjectURL(this.src);
        });
        image.src = URL.createObjectURL(img);
        return dfd.promise()
      })
    })).then(function() {
      nav.find("a").each(function() {
        console.log(this.href + "'n");
      })
    })
  });
})

jsfiddlehttps://jsfiddle.net/bc6x3s02/19/