JS Canvas-用Alpha放置图像数据?

时间:2012-01-22 18:37:25

标签: javascript ipad html5 canvas opacity

我有一个ipad webapp我正在努力在画布上绘制并保存它。就像一个更基本的油漆程序。我需要能够上传和图像到背景并在上面绘图。现在这不会太困难,因为我得到了绘图功能,并且将图像打印到背景并在其上绘制并不困难。我遇到的问题是它还需要具有可管理的层。这意味着它需要支持alpha像素。

所以我所做的就是编写一个面板类,当调用paint时,它会向下移动它的子面板并将其缓冲的图像绘制到临时图像。然后我把它画在父母上面 - 继续,直到图像变平为临时图像。

这很好用 - 特别是在桌面上。但要实现这一点,我必须从头开始编写putImageData代码,这些代码循环遍历像素数组并绘制它们以考虑alpha。像这样 -

    var offset = (canvasW*4*y)+x*4;
    for(var r = 0; r < newHeight; r++)
    {
        var lineOffset = (size.width*4 - columns)*r + offset;
        for(var c = 0; c < columns; c+=4)
        {
            var start = (r*columns)+c;
            var destStart = start+lineOffset;
            var red = imageData[start];
            var green = imageData[start+1];
            var blue = imageData[start+2];
            var alpha = imageData[start+3];

            var destRed = canvasData[destStart];
            var destGreen = canvasData[destStart+1];
            var destBlue = canvasData[destStart+2];
            var destAlpha = canvasData[destStart+3];

            var opacity = alpha/255;
            var destOpacity = destAlpha/255;
            var invOpacity = 1-opacity;

            var newRed = Math.abs(red - ((red-destRed)*invOpacity));
            var newGreen = Math.abs(green - ((green-destGreen)*invOpacity));
            var newBlue = Math.abs(blue - ((blue-destBlue)*invOpacity));

            canvasData[start+lineOffset] = newRed;
            canvasData[start+lineOffset+1] = newGreen;
            canvasData[start+lineOffset+2] = newBlue;
            canvasData[start+lineOffset+3] = 255;
        }
    }

每层大约需要50毫秒。桌面不太好用。需要高达1200毫秒的ipad!所以我用原始的putImageData(它不支持alpha)测试它,它仍然不是很令人印象深刻,但它是我想到的最好的。

所以这是我的问题。我知道用画布绘制有一些不透明度,但它需要能够绘制一些完全不透明的像素和一些完全透明的像素。是否有包含不透明度的putImageData?

如果没有关于如何实现这一目标的任何建议?

1 个答案:

答案 0 :(得分:0)

正如@Jeffrey Sweeney所提到的,尝试将画布堆叠在一起。对于我的一个Javascript库CInk(在那里搜索z-index),我做了同样的事情。

我有一个容器div,我填充了许多canvas个DOM来模仿图层。所有canvas DOM都是绝对定位的,z-index定义了图层的顺序。在您的情况下,您将必须在特定图层应用样式以设置其不透明度。