如何制作涂抹工具算法?

我正在创建一种涂抹工具的算法,但是必须逐个像素地完成。

涂抹工具的概念很简单

onmouseMove-使用画笔模板将旧点的像素复制到新点

如何制作涂抹工具算法?

我在按位运算中遇到问题。该算法无法正确绘制像素。(我是从头开始创建此算法的,因此可能会出现一些愚蠢的错误)

diameter = brush.size;
_bitData = _canvas.bitmapData;
_bitwidth = _bitData.rect.width;//width of canvas

_bitVector = _bitData.getVector();//1d vector of uint

_brushVector = brush.bitmapData.getVector();//1d vector of uint

brushVectorIndex = 0;
for(yIndex = 0; yIndex < diameter; yIndex++)
{
    for(xIndex = 0; xIndex < diameter; xIndex++)
    {
        yCor = yIndex + oldY;
        xCor = xIndex + oldX;

        if(_bitData.rect.contains(xCor,yCor))
        {
            bitVectorIndex_old      = (yCor * _bitWidth)        + xCor;
            bitVectorIndex_new      = ((Y+yIndex) * _bitWidth)  + X+xIndex;

            //Creating alpha map of brush and old mouse point's pixel
            brushPixelAlpha = (_brushVector[brushVectorIndex] & _bitVector[bitVectorIndex_old] & 0xFF000000);

            //Adding colors to the aplha map according to old mouse point's pixel
            brushPixel = brushPixelAlpha | (_bitVector[bitVectorIndex_old] & 0x00FFFFFF);

            //Create alpha map for new pixel
            pixelAlpha = ((brushPixel | _bitVector[bitVectorIndex_new]) & 0xFF000000)

            //Adding color to pixel alpha map using brush's stamp 
            pixel =  pixelAlpha | (brushPixel & 0x00FFFFFF);

            _bitVector[bitVectorIndex_new] = pixel;
        }
        brushVectorIndex++;
    }
}
_bitData.setVector(_bitVector);

如果您可以提出如何优化此代码的建议,那么这也将有所帮助,因为该代码每帧将运行10000s。

编辑:提出了一个可行的解决方案。上面的按位运算是非常错误的。以下代码未经过优化,但可以运行。

private function smudgeIt(brush:uint,oldmouse:uint,newMouse:uint):uint
        {
            var pixel:uint;
            var bA:uint = (brush>>24)&0xff;
            var oA:uint = (oldmouse>>24)&0xff;

            var oldAlpha:uint = oA<bA?oA:bA;

            var rOld:uint,gOld:uint,bOld:uint;
            var rNew:uint,gNew:uint,bNew:uint;

            rOld = (oldmouse >>16) & 0xff;
            gOld = (oldmouse >>8)  & 0xff;
            bOld = (oldmouse       & 0xff);

            rNew = (newMouse >>16) & 0xff;
            gNew = (newMouse >>8)  & 0xff;
            bNew = (newMouse       & 0xff);

            var newAlpha:uint = ((newMouse>>24)&0xff)-oldAlpha;
            newAlpha = newAlpha<0?0:newAlpha;

            rNew = (rNew*newAlpha + rOld*oldAlpha)/255;
            gNew = (gNew*newAlpha + gOld*oldAlpha)/255;
            bNew = (bNew*newAlpha + bOld*oldAlpha)/255;

            var finalAlpha:uint = ((newMouse >> 24) & 0xff)+oldAlpha;
            finalAlpha = finalAlpha>255?255:finalAlpha;

            pixel = finalAlpha<<24 | rNew << 16 | gNew << 8 | bNew;

            return pixel;
        }
jinhuluntai 回答:如何制作涂抹工具算法?

alpha通道的含义有些混乱。
如果用旧笔刷覆盖新位置的RGB通道,则显示的代码:

RGB_new = RGB_old | RGB_brush;
alpha_new = alpha_new | (alpha_old & alpha_brush);

这不是您想要的,您失去了所有在新位置上的颜色信息(因此未将其混合),更糟糕的是,如果笔刷确实具有RGB信息,您将饱和所有通道,直到获得纯白色。
让我们暂时忘掉Alpha通道,让我们从普通的不透明RGB形式开始。
正如您所描述的,画笔用作位掩码:如果将位设置为1,则从旧位置获取像素,否则从新位置获取像素。假设将8位mask8 = mask1*16rFF)应用于1个像素的1-8位通道:

R_new = (R_new & (256-mask8)) | (R_old & mask8);

现在假定使用24位掩码((mask8<<16)|(mask8<<8)|mask8mask8*0x10100mask1*16rFFFFFF重复8次掩码,这可以同时应用于3个通道:

RGB_new = (RGB_new & (~mask24)) | (R_old & mask24);

如果您想通过Alpha通道来使事物复杂化(这是一种渐进的透明性,而不是全有或全无),那么您将不得不描述如何混合使用旧的和新的位,但是我认为然后,笔刷将是Alpha通道本身。

一种经典算法(alpha混合)具有R_new = R_new * (1-alpha) + R_old * alpha,其中alpha是0到1之间的一个分数。它可以用alpha(介于0(透明)和0xFF(不透明)之间)的整数算术执行:

R_new = (R_new * (255-alpha) + R_old*alpha) / 255;

通过一些技巧,您可以在R_B通道和A_G_通道上多路复用操作。您可以在此站点上找到一些这些alpha混合位的技巧。在确实由Dan Ingalls在Smalltalk上下文http://bugs.squeak.org/view.php?id=7803中发明了所有BitBlt操作之后,我确实将其中一些应用到了Squeak VM https://en.wikipedia.org/wiki/Bit_blit,所以我们必须归还凯撒。

在这里,我们没有考虑新旧像素的固有透明度,我们可以定义更复杂的操作以将其考虑在内,但这意味着什么?如果它们是透明的,我们后面会看到什么?

本文链接:https://www.f2er.com/3102503.html

大家都在问