A BitmapData can be seen as an array of length width*height, holding unsigned int colors values. There are at least four ways to manipulate pixels of a bitmap image(Bitmap/BitmapData) in OpenFL.
The first way is using setPixel() or setPixel32() function:
var myBitmapData:BitmapData = new BitmapData(800, 600, true, 0);
myBitmapData.lock();
for (j in 0...600)
{
for (i in 0...200)
{
myBitmapData.setPixel32(i, j, (i % 255) << 24 | 0x0000ff);
}
}
myBitmapData.unlock();
You can use lock() and unlock() function before and after multiple calls of setPixel() function, so the BitmapData will only be updated on Screen after unlock().
The second way is using setVector() function, and a Vector of UInt to hold pixel values:
var myVector:Vector = new Vector(200 * 600, true);
for (j in 0...600)
{
for (i in 0...200)
{
myVector[j * 200 + i] = (i % 255) << 24 | 0x0000ff;
}
}
var myRect2:Rectangle = new Rectangle(200, 0, 200, 600);
myBitmapData.setVector(myRect2,myVector);
The third way is using setPixels() function, and a ByteArray to hold pixel values:
var myByteArray:ByteArray = new ByteArray(200 * 600 * 4);
for (j in 0...600)
{
for (i in 0...200)
{
//myByteArray.position = (j * 200 + i) * 4;
myByteArray.writeUnsignedInt((i % 255) << 24 | 0x0000ff);
}
}
var myRect4:Rectangle = new Rectangle(400, 0, 200, 600);
myByteArray.position = 0;
myBitmapData.setPixels(myRect4,myByteArray);
Remember to set the position of the ByteArray to 0 before calling setPixels(). The position "(j * width + i) * 4" of the ByteArray is associated with the pixel at (x=i,y=j) in the BitmapData. There is no need to set the position of the ByteArray to "(j * 200 + i) * 4" above since in the double for loops the "writeUnsignedInt()" function will update the position automatically.
The fourth way is using the Memoery API, which is similar to the third way. See https://bruce-lab.blogspot.com/2013/03/fast-way-for-per-pixel-bitmap.html for more details.
var myMem:ByteArray = new ByteArray(200 * 600 * 4);
Memory.select(myMem);
for (j in 0...600)
{
for (i in 0...200)
{
Memory.setI32((j * 200 + i) * 4, (i % 255) << 24 | 0x0000ff);
}
}
var myRect4:Rectangle = new Rectangle(600, 0, 200, 600);
myMem.position = 0;
myBitmapData.setPixels(myRect4,myMem);
The full source code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package; | |
import openfl.display.Sprite; | |
import openfl.display.Bitmap; | |
import openfl.display.BitmapData; | |
import openfl.geom.Rectangle; | |
import openfl.Vector; | |
import openfl.utils.ByteArray; | |
import openfl.Memory; | |
import openfl.Lib; | |
/** | |
* ... | |
* @author Bruce [https://bruce-lab.blogspot.com/] | |
* Four ways for per pixel bitmap manipulation in OpenFL | |
*/ | |
class Main extends Sprite | |
{ | |
public function new() | |
{ | |
super(); | |
var myBitmapData:BitmapData = new BitmapData(800, 600, true, 0); | |
addChild(new Bitmap(myBitmapData)); | |
//Way 1: using setPixel(32) | |
myBitmapData.lock(); | |
for (j in 0...600) | |
{ | |
for (i in 0...200) | |
{ | |
myBitmapData.setPixel32(i, j, (i % 255) << 24 | 0x0000ff); | |
} | |
} | |
myBitmapData.unlock(); | |
//Way 2: using setVector | |
var myVector:Vector<UInt> = new Vector<UInt>(200 * 600, true); | |
for (j in 0...600) | |
{ | |
for (i in 0...200) | |
{ | |
myVector[j * 200 + i] = (i % 255) << 24 | 0x0000ff; | |
} | |
} | |
var myRect2:Rectangle = new Rectangle(200, 0, 200, 600); | |
myBitmapData.setVector(myRect2,myVector); | |
//Way 3: using setPixels | |
var myByteArray:ByteArray = new ByteArray(200 * 600 * 4); | |
for (j in 0...600) | |
{ | |
for (i in 0...200) | |
{ | |
//myByteArray.position = (j * 200 + i) * 4; | |
myByteArray.writeUnsignedInt((i % 255) << 24 | 0x0000ff); | |
} | |
} | |
var myRect4:Rectangle = new Rectangle(400, 0, 200, 600); | |
myByteArray.position = 0; | |
myBitmapData.setPixels(myRect4,myByteArray); | |
//Way 4: using Memory API and setPixels | |
//[https://bruce-lab.blogspot.com/2013/03/fast-way-for-per-pixel-bitmap.html] | |
var myMem:ByteArray = new ByteArray(200 * 600 * 4); | |
Memory.select(myMem); | |
for (j in 0...600) | |
{ | |
for (i in 0...200) | |
{ | |
Memory.setI32((j * 200 + i) * 4, (i % 255) << 24 | 0x0000ff); | |
} | |
} | |
var myRect4:Rectangle = new Rectangle(600, 0, 200, 600); | |
myMem.position = 0; | |
myBitmapData.setPixels(myRect4,myMem); | |
}//end of function new | |
}//end of class Main |