用javascript手工创建图像并相对于alpha通道绘制?

时间:2010-11-07 13:47:33

标签: javascript html5 canvas

我目前正在尝试使用动态生成的图像创建一个页面,这些图像不是形状,绘制到画布中以创建动画。

我尝试的第一件事是:

//create plenty of those:
var imageArray = ctx.createImageData(0,0,16,8);
//fill them with RGBA values...
//then draw them
ctx.putImageData(imageArray,x,y);

问题是图像是重叠的,而putImageData只是......将数据放在上下文中,与w3c中指定的alpha通道无关:

  

画布中的像素被批量替换,没有合成,alpha混合,没有阴影等。

所以我想,我怎样才能使用Image而不是ImageData s?

我试图找到一种方法将ImageData对象实际放回到图像中,但看起来它只能放在画布上下文中。因此,作为最后的手段,我尝试使用16x8画布的toDataURL()方法(我的图像大小),并将结果粘贴为我的~600幅图像的src

结果很漂亮,但是我吃了100%的CPU ...(它没有putImageData,~5%cpu)我的猜测是因为一些未知的原因,图像重新出现每次绘制时都从image/png数据URI加载......但这很奇怪......不是吗?它似乎比我以前的技术需要更多的RAM。

所以,结果,我不知道如何实现我的目标。

如何在javascript中动态创建alpha-channeled图像,然后在画布上以相当快的速度绘制它们?

是使用Java小程序的唯一真正替代方案吗?

感谢您的时间。

3 个答案:

答案 0 :(得分:3)

不知道,你真正想要实现的目标:

您是否看过渲染上下文的drawImage - 方法? 基本上,它为你做了组合(由globalCompositeOperation - 属性指定) - 它允许你传入一个canvas元素作为源。

所以可能会做一些事情:

var offScreenContext = document.getCSSCanvasContext( "2d", "synthImage", width, height);
var pixelBuffer = offScreenContext.createImageData( tileWidth, tileHeight );
// do your image synthesis and put the updated buffer back into the context:
offScreenContext.putImageData( pixelBuffer, 0, 0, tileOriginX, tileOriginY, tileWidth, tileHeight );
// assuming 'ctx' is the context of the canvas that actually gets drawn on screen
ctx.drawImage(
  offScreenContext.canvas,                          // => the synthesized image
  tileOriginX, tileOriginY, tileWidth, tileHeight,  // => frame of offScreenContext that get's drawn
  originX, originY, tileWidth, tileHeight           // => frame of ctx to draw in
);

假设你有一个想要循环的动画,这有一个额外的好处,就是只需要在某种精灵图中生成一次帧,这样在后续的迭代中你只需要调用{{ 1}} - 以增加内存占用为代价......

答案 1 :(得分:0)

为什么不使用SVG?

如果你必须使用画布,也许你可以自己在画布上实现绘画?

var red = oldred*(1-alpha)+imagered*alpha

......等等......

答案 2 :(得分:0)

getCSSCanvasContext似乎只是WebKit,但您也可以创建这样的屏幕外画布:

var canvas = document.createElement('canvas')
canvas.setAttribute('width',300);//use whatever you like for width and height
canvas.setAttribute('height',200);

然后您可以使用drawImage方法绘制并绘制到另一个画布上。