Actionscript 3 在ActionScript中迭代位图图像的每个像素
是否可以迭代位图图像的每个像素?最终,我试图实现的是,我需要获得位图图像中每个像素的坐标值,并根据它们的坐标值更改这些像素的颜色。在我看来,我需要使用getPixels()方法,但我仍然不清楚应该做什么。您需要一个BitmapData对象。然后,它是一个简单的直接嵌套循环: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
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();