使用画布创建桌面通知图像,只有一个图像在后台页面中工作

时间:2014-04-25 04:38:08

标签: javascript canvas google-chrome-extension html5-canvas

我在后台页面中使用canvas创建桌面通知的数据网址时出现问题'图像。

我想使用"图像" notifications需要3:2的比例才能正常显示。我想要使​​用的图像(来自hulu.com)是不同的比例,因此我决定使用canvas元素从这些图像创建相应的数据URL,以使比率正确。它在理论上有用,但是......

...如果我在后台页面中创建多个画布/通知,我会遇到问题。一张图片正确创建,但其余图片都是空的。

令人困惑的是,在新选项卡中打开相同的背景页面(即完全相同的代码)会使一切正常:所有通知都是使用从hulu.com加载的图像创建的。此外,只需将尺寸从360x240更改为300x200即可使用。最后,虽然它们是具有相同Chrome版本(34.0.1847.116)的类似计算机,但它在工作时无需修改,但它不在我自己的笔记本电脑上。

我在这篇文章的底部提供了一个测试扩展。基本上,它只有一个生成的背景页面。该页面的代码是:

var images = ["http://ib2.huluim.com/video/60376901?size=290x160&img=1",
    "http://ib2.huluim.com/video/60366793?size=290x160&img=1",
    "http://ib4.huluim.com/video/60372951?size=290x160&img=1",
    "http://ib1.huluim.com/video/60365336?size=290x160&img=1",
    "http://ib3.huluim.com/video/60376290?size=290x160&img=1",
    "http://ib4.huluim.com/video/60377231?size=290x160&img=1",
    "http://ib4.huluim.com/video/60312203?size=290x160&img=1",
    "http://ib1.huluim.com/video/60376972?size=290x160&img=1",
    "http://ib4.huluim.com/video/60376971?size=290x160&img=1",
    "http://ib1.huluim.com/video/60376616?size=290x160&img=1"];

for (var i = 0; i < 10; i++) {
    getDataURL(i);
}

/*
 * Gets the data URL for an image URL
 */
function getDataURL(i) {
    var img = new Image();

    img.onload = function() {
        var canvas = document.createElement('canvas');
        canvas.width = 360;
        canvas.height = 240;
        var ctx = canvas.getContext('2d');

        ctx.drawImage(this, 0, 0);
        ctx.fillStyle = "rgb(200,0,0)";
        ctx.fillRect (10, 10, 55, 50);
        var dataURL = canvas.toDataURL('image/png');
        chrome.notifications.create('', {
            type: 'image',
            iconUrl: 'logo_128x128.png',
            title: String(i),
            message: 'message',
            imageUrl: dataURL
        }, function(id) {});
    }

    //img.src = chrome.extension.getURL('logo_128x128.png');;
    img.src = images[i];
}

img.src = ...的注释掉的行是一个加载本地文件而不是远程文件的测试。在这种情况下,将创建所有图像。

添加到画布的红色矩形表示它不仅仅是远程图像的问题:整个结果画布为空,没有任何红色矩形。

如果您下载并添加下面的测试扩展程序,则应该收到10个通知,但只有一个通知图像。

然后,要在新标签页中打开背景页面,您可以检查背景页面,在控制台中输入:

chrome.extension.getURL('_generated_background_page.html')

并右键点击该网址,然后点击&#34;在新标签中打开&#34; (或窗口)。一旦打开,您应该收到10个看起来很好的通知。

知道发生了什么事吗?我还没有找到与此相关的背景页面的任何限制。任何帮助将不胜感激,因为这一直让我疯狂!

此处提供的文件:https://www.dropbox.com/s/ejbh6wq0qixb7a8/canvastest.zip


编辑:根据@ GameAlchemist的评论,我还尝试了以下方法:相同的getDataURL方法,但是徽标包含在onload内的循环:

function loop() {
    for (var i = 0; i < 10; i++) {
        getDataURL(i);
    }
}

var logo = new Image();
logo.onload = function () {
    loop();
}
logo.src = chrome.extension.getURL('logo_128x128.png');

1 个答案:

答案 0 :(得分:3)

请记住,create()方法是异步的,你应该使用回调。回调可以调用下一个图像获取。

我建议分两步执行此操作:

  1. 首先加载所有图像
  2. 处理图像队列
  3. 原因是您可以通过这种方式更好地利用异步图像加载,而不是链接回调,这会强制您加载一个和一个图像。

    例如:

    图像加载器

    var urls = ["http://ib2.huluim.com/video/60376901?size=290x160&img=1",
        "http://ib2.huluim.com/video/60366793?size=290x160&img=1",
        "http://ib4.huluim.com/video/60372951?size=290x160&img=1",
        "http://ib1.huluim.com/video/60365336?size=290x160&img=1",
        "http://ib3.huluim.com/video/60376290?size=290x160&img=1",
        "http://ib4.huluim.com/video/60377231?size=290x160&img=1",
        "http://ib4.huluim.com/video/60312203?size=290x160&img=1",
        "http://ib1.huluim.com/video/60376972?size=290x160&img=1",
        "http://ib4.huluim.com/video/60376971?size=290x160&img=1",
        "http://ib1.huluim.com/video/60376616?size=290x160&img=1"];
    
    var images = [],            // store image objects
        count = urls.length;    // for loader
    
    for (var i = 0; i < urls.length; i++) {
        var img = new Image;         // create image
        img.onload = loader;         // share loader handler
        img.src = urls[i];           // start loading
        images.push(img);            // push image object in array
    }
    
    function loader() {
        count--;
        if (count === 0) process();  // all loaded, start processing
    }
    //TODO need error handling here as well
    

    <强> Fiddle with concept code for loader

    处理

    现在处理可以与加载隔离:

    function process() {
    
        // share a single canvas (use clearRect() later if needed)
        var canvas = document.createElement('canvas'),
            ctx = canvas.getContext('2d'),
            current = 0;
    
        canvas.width = 360;
        canvas.height = 240;
    
        createImage();             // invoke processing for first image
    
        function createImage() {
    
            ctx.drawImage(images[current], 0, 0); // draw current image
            ctx.fillStyle = "rgb(200,0,0)";
            ctx.fillRect (10, 10, 55, 50);
    
            chrome.notifications.create('', {
                type    : 'image',
                iconUrl : 'logo_128x128.png',
                title   : String(i),
                message : 'message',
                imageUrl: canvas.toDataURL()  // png is default
    
            },
            function(id) {                    // use callback
                current++;                    // next in queue
                if (current < images.length) {
                    createImage();            // call again if more images
                }
                else {
                    done();                   // we're done -> continue to done()
                }
            });
        }
    }
    

    免责声明:我没有测试Chrome扩展程序的测试环境,因此可能存在错别字/错误。

    希望这有帮助!