Повторение каждого пикселя растрового изображения в ActionScript - PullRequest
0 голосов
/ 11 марта 2011

Возможно ли повторять каждый пиксель растрового изображения?В конечном итоге я пытаюсь добиться того, что мне нужно получить значения координат каждого пикселя растрового изображения и изменить цвет этих пикселей в соответствии с их значениями координат.На мой взгляд, мне нужно использовать метод getPixels (), но я все еще не понимал, что мне делать.

Ответы [ 3 ]

3 голосов
/ 11 марта 2011

(слишком медленно :)), так что это то же самое, что и выше, с линейным циклом вместо 2 вложенных циклов.

//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

обратите внимание, что если вы используете bitmapData с альфа-каналом (скажем,если вы загрузите изображение, альфа включится автоматически) вам придется использовать

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
    }
}
}

для 100* (100 * 100) getPixel, самый быстрый (на моей машине) - это однострочный цикл for с локальными переменными.(+/- 250 мс), затем однострочный, в то время как (+/- 330 мс):)

хранение локальных переменных w и h для ширины и высоты делает циклы for в два раза быстрее :)

Полезно знать

3 голосов
/ 14 марта 2011

Если, как вы говорите, вы устанавливаете пиксели только на основе их x и y, вам не нужны ни getPixel (), ни getPixels ()!

myBitmapData.lock();

for( var j:int = 0; j < myBitmapData.height; j++ )
{
    for( var i:int = 0; i < myBitmapData.width; i++ )
    {
        var alpha:uint = 0xFF000000;  // Alpha is always 100%
        var red:uint = 0x00FF0000 * ( i / myBitmapData.width );  // Set red based on x
        var green:uint = 0x0000FF00 * ( j / myBitmapData.height );  // Set green based on y
        var newColor:uint = alpha + red + green;  // Add the components

        // Set the new pixel value (setPixel32() includes alpha, e.g. 0xFFFF0000 => alpha=FF, red=FF, green=00, blue=00)
        myBitmapData.setPixel32( i, j, newColor );
    }
}

myBitmapData.unlock();

Если, однако, вы хотите прочитать текущее значение пикселей, позвольте мне присоединиться к соревнованию по скорости.

В дополнение к более ранним ответам, здесь есть еще большее увеличение скорости!

Вместо многочисленных вызовов getPixel () вы можете использовать getPixels () для получения байтового массива данных пикселей.

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();
3 голосов
/ 11 марта 2011

Вам нужен объект 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.
   }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...