【问题标题】:Javascript canvas how to drawImage a lot of imagesJavascript画布如何drawImage很多图像
【发布时间】:2014-10-17 00:22:23
【问题描述】:

如何在画布上绘制大量图像?

我有很多图像 url 数组,需要输出它。性能好怎么办。

我的示例代码(jsfiddle:http://jsfiddle.net/6sunguw4/):

 $(document).ready(function () {
            var bgCanvas = document.getElementById("bgCanvas");
            var bgCtx = bgCanvas.getContext("2d");

            bgCanvas.width = window.innerWidth;
            bgCanvas.height = window.innerHeight + 200;


            var array = new Array();
            array[1] = 'https://developer.chrome.com/webstore/images/calendar.png';
            array[2] = 'http://www.w3schools.com/html/html5.gif';
            array[3] = 'http://www.linosartele.lt/wp-content/uploads/2014/08/images-9.jpg';

            img0 = new Image();
            img0.onload = function() {
                bgCtx.drawImage(img0, 0,0, 100, 100);
            }
            img0.src = array[1];


            img2 = new Image();
            img2.onload = function() {
                bgCtx.drawImage(img2, 100,0, 100, 100);
            }
            img2.src = array[2];

            img3 = new Image();
            img3.onload = function() {
                bgCtx.drawImage(img3, 200,0,100,100);
            }
            img3.src = array[3];
        });

【问题讨论】:

    标签: javascript html canvas


    【解决方案1】:

    这里的代码可以从您放入数组的 URL 中加载所有图像,而无需手动编写代码 2000 次 new Image/.onload/.drawImage(我在下面的示例代码中调用数组 imageURLs):

    // image loader
    
    // put the paths to your images in imageURLs[]
    var imageURLs=[];  
    // push all your image urls!
    imageURLs.push('https://developer.chrome.com/webstore/images/calendar.png');
    imageURLs.push('http://www.w3schools.com/html/html5.gif');
    imageURLs.push('http://www.linosartele.lt/wp-content/uploads/2014/08/images-9.jpg');
    
    // the loaded images will be placed in imgs[]
    var imgs=[];
    
    var imagesOK=0;
    loadAllImages(start);
    
    function loadAllImages(callback){
        for (var i=0; i<imageURLs.length; i++) {
            var img = new Image();
            imgs.push(img);
            img.onload = function(){ 
                imagesOK++; 
                if (imagesOK>=imageURLs.length ) {
                    callback();
                }
            };
            img.onerror=function(){alert("image load failed");} 
            img.crossOrigin="anonymous";
            img.src = imageURLs[i];
        }      
    }
    
    function start(){
    
        // the imgs[] array now holds fully loaded images
        // the imgs[] are in the same order as imageURLs[]
    
        bgCtx.drawImage(imgs[0], 000,0, 100, 100);
        bgCtx.drawImage(imgs[1], 100,0, 100, 100);
        bgCtx.drawImage(imgs[2], 200,0, 100, 100);
    
    }
    

    为了获得更好的加载性能:

    浏览器通常一次只能从一个域下载 6-8 个文件。因此,您的 2000 张图片需要 2000/8 == 250 次单独的连续调用您的域才能加载。

    您可以将您的 2000 组合成一个或多个精灵表(最好是 6 个或更少的精灵表)。这样,浏览器可以一次下载包含 2000 张图片的 1-6 张 spritesheets。

    您可以使用 context.drawImage 的扩展版本从 spritesheet 中提取任何所需的图像。例如,假设您需要的图像位于 spritesheet 上的 [200,200] 处,大小为 100x100。您可以像这样在画布上绘制该图像:

    bgCtx.drawImage(spritesheet,
        200,200,100,100    // clip the image from the spritesheet at [200,200] with size 100x100
        125,250,100,100    // draw the clipped image on the canvas at [125,250]
    );
    

    【讨论】:

    • @Asker。删除img.crossOrigin="anonymous",它应该可以工作。我在自己的项目中默认设置了这个标志,但如果你正在加载跨域图像,它必须被删除。 ;-)
    【解决方案2】:

    您对代码本身无能为力。 drawImage 似乎非常优化,而图像的原始数量可能会减慢速度。

    根据您的目标,您可以做的一件事是准备合成图像。例如,这 3 个图像可以很容易地转换为单个 PNG 图像,然后只需要一次 drawImage 调用。但是,如果您打算改变它们的位置或某些效果,恐怕您会被现有的东西所困扰。

    【讨论】:

    • 如何输出所有数组,因为我有很多 2000 左右的图像,我不会写手..
    • 循环遍历数组并绘制每个数组。您想要实现什么目标,为什么要使用画布?
    猜你喜欢
    • 1970-01-01
    • 2013-11-01
    • 2013-12-22
    • 2011-05-10
    • 2018-12-25
    • 2012-05-01
    • 2014-05-12
    • 1970-01-01
    • 2015-11-01
    相关资源
    最近更新 更多