Actionscript 3 在ActionScript中迭代位图图像的每个像素

Actionscript 3 在ActionScript中迭代位图图像的每个像素,actionscript-3,Actionscript 3,是否可以迭代位图图像的每个像素?最终,我试图实现的是,我需要获得位图图像中每个像素的坐标值,并根据它们的坐标值更改这些像素的颜色。在我看来,我需要使用getPixels()方法,但我仍然不清楚应该做什么。您需要一个BitmapData对象。然后,它是一个简单的直接嵌套循环: var pix : int; //AS3 uses int even for uint types for (var x:int = 0; x < myBitmapData.width; x++) { for

是否可以迭代位图图像的每个像素?最终,我试图实现的是,我需要获得位图图像中每个像素的坐标值,并根据它们的坐标值更改这些像素的颜色。在我看来,我需要使用getPixels()方法,但我仍然不清楚应该做什么。

您需要一个BitmapData对象。然后,它是一个简单的直接嵌套循环:

var pix : int; //AS3 uses int even for uint types

for (var x:int = 0; x < myBitmapData.width; x++)
{
   for (var y:int = 0; y < myBitmapData.height; y++)
   {
      // This'll get you the pixel color as RGB
      pix = myBitmapData.getPixel(x,y);
      // To change the color, use the setPixel method + the uint corresponding
      // to the new color.
   }

}
var-pix:int//AS3甚至对uint类型使用int
对于(变量x:int=0;x
(太慢:) 这就是上面的sae,它是一个线性循环,而不是两个嵌套循环

//creates a new BitmapData, with transparency, white 0xFFFFFF
var bd:BitmapData = new BitmapData( 100, 100, false, 0xFFFFFF );

//stores the width and height of the image
var w:int = bd.width;
var h:int = bd.height;

var i:int = w * h;

var x:int, y:int, col;
//decremental loop are said to be faster :)
while ( i-- )
{
    //this is the position of each pixel in x & y
    x = i % w;
    y = int( i / w );

    //gets the current color of the pixel ( 0xFFFFFF )
    col = bd.getPixel( x, y );

    //assign the 0xFF0000 ( red ) color to the pixel
    bd.setPixel( x, y, 0xFF0000 );

}
addChild( new Bitmap( bd ) );//a nice red block
请注意,如果使用带有alpha通道的位图数据(例如,如果加载图像,alpha将自动打开),则必须使用

bd.getPixel32( x, y );// returns a uint : 0xFF000000
//and
bd.setPixel32( x, y, UINT );// 0xFF000000
编辑:我做了一个快速测试:

package  
{
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.utils.getTimer;
public class pixels extends Sprite 
{
    private var bd:BitmapData = new BitmapData( 100, 100, false, 0xFFFFFF );
    public function pixels() 
    {
        var i:int, total:int = 100, t:int = 0;

        t = getTimer();
        i = total;
        while( i-- )
        {
            whileLoop( bd );
        }
        trace( 'while:', getTimer() - t );

        t = getTimer();
        i = total;
        while( i-- )
        {
            forLoop( bd );
        }
        trace( 'for:', getTimer() - t );
    }

    private function forLoop( bd:BitmapData ):void 
    {
        var i:int, j:int;
        var col:int;

        for ( i = 0; i < bd.width; i++ ) 
        {
            for ( j = 0; j < bd.height; j++ )
            {
                col = bd.getPixel( i, j ); // +/- 790 ms
            }
        }

        //for ( i = 0; i < bd.width; i++ ) for ( j = 0; j < bd.height; j++ ) col = bd.getPixel( i, j ); // +/-530 ms

        //var w:int = bd.width;
        //var h:int = bd.height;
        //for ( i = 0; i < w; i++ ) for ( j = 0; j < h; j++ ) col = bd.getPixel( i, j ); // +/-250 ms

    }

    private function whileLoop( bd:BitmapData ):void 
    {
        var w:int = bd.width;
        var h:int = bd.height;
        var i:int = w * h;
        var col:int;
        while ( i-- ) 
        {
            col = bd.getPixel( i % w, int( i / w ) ); //  +/- 580 ms
        }
        //while ( i-- ) col = bd.getPixel( i % w, int( i / w ) ); //  +/- 330 ms
    }
}
}
包
{
导入flash.display.BitmapData;
导入flash.display.Sprite;
导入flash.utils.getTimer;
公共类像素扩展了Sprite
{
私有变量bd:BitmapData=新的BitmapData(100100,false,0xFFFFFF);
公共功能像素()
{
变量i:int,总计:int=100,t:int=0;
t=getTimer();
i=总数;
而(我--)
{
whileLoop(bd);
}
跟踪('while:',getTimer()-t);
t=getTimer();
i=总数;
而(我--)
{
forLoop(bd);
}
跟踪('for:',getTimer()-t);
}
私有函数forLoop(bd:BitmapData):void
{
变量i:int,j:int;
var-col:int;
对于(i=0;i
对于100*(100*100)getPixel,最快的(在我的机器上)是带有局部变量的一行for循环。(+/-250毫秒)然后是单线,而(+/-330毫秒):)

为宽度和高度存储局部变量w和h会使for循环速度加快两倍:)


很高兴知道

如果,如您所说,您仅根据像素的x和y设置像素,则不需要getPixel()或getPixels()

myBitmapData.lock();
对于(var j:int=0;jalpha=FF、红色=FF、绿色=00、蓝色=00)
设置像素32(i,j,newColor);
}
}
myBitmapData.unlock();
但是,如果您想读取像素的当前值,让我加入速度竞赛

除了前面的答案,这里有更多的速度增加

您可以使用getPixels()来获取像素数据的字节数组,而不是大量调用getPixel()

myBitmapData.lock();

var numPixels:int = myBitmapData.width * myBitmapData.height;
var pixels:ByteArray = myBitmapData.getPixels( new Rectangle( 0, 0, myBitmapData.width, myBitmapData.height ) );
for( var i:int = 0; i < numPixels; i++ )
{
    // Read the color data
    var color:uint = pixels.readUnsignedInt();

    // Change it if you like

    // Write it to the pixel (setPixel32() includes alpha, e.g. 0xFFFF0000 => alpha=FF, red=FF, green=00, blue=00)
    var theX:int = i % myBitmapData.width;
    myBitmapData.setPixel32( theX, ( i - theX ) / myBitmapData.width, color );
}

myBitmapData.unlock();
myBitmapData.lock();
var numPixels:int=myBitmapData.width*myBitmapData.height;
var pixels:ByteArray=myBitmapData.getPixels(新矩形(0,0,myBitmapData.width,myBitmapData.height));
对于(变量i:int=0;ialpha=FF、红色=FF、绿色=00、蓝色=00)
var theX:int=i%myBitmapData.width;
设置像素32(theX,(i-theX)/myBitmapData.width,color);
}
myBitmapData.unlock();

IMHO,不需要存储宽度和高度(这些是属性,而不是方法)。但是很好的解决方案:)谢谢:)嗯,我还没有做基准测试。我认为通过getter访问对象的属性比处理局部变量要慢。我可能错了+我是某种局部变量狂人^^用模和除法得到x和y,为什么不两个嵌套循环呢?如果要使用setPixel,就应该使用.lock()和.unlock()来不更新每一步引用它的对象,请参见Lol,我在其中添加了一些C语法。新习惯。谢谢你,伊桑!
myBitmapData.lock();

var numPixels:int = myBitmapData.width * myBitmapData.height;
var pixels:ByteArray = myBitmapData.getPixels( new Rectangle( 0, 0, myBitmapData.width, myBitmapData.height ) );
for( var i:int = 0; i < numPixels; i++ )
{
    // Read the color data
    var color:uint = pixels.readUnsignedInt();

    // Change it if you like

    // Write it to the pixel (setPixel32() includes alpha, e.g. 0xFFFF0000 => alpha=FF, red=FF, green=00, blue=00)
    var theX:int = i % myBitmapData.width;
    myBitmapData.setPixel32( theX, ( i - theX ) / myBitmapData.width, color );
}

myBitmapData.unlock();