我在后台页面中使用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');
答案 0 :(得分:3)
请记住,create()方法是异步的,你应该使用回调。回调可以调用下一个图像获取。
我建议分两步执行此操作:
原因是您可以通过这种方式更好地利用异步图像加载,而不是链接回调,这会强制您加载一个和一个图像。
例如:
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扩展程序的测试环境,因此可能存在错别字/错误。
希望这有帮助!