Im converting a image into a linear 1 bit array is this the fastest way to it?
btw Sprite.sensibleResult is a threeshold number. Like 0x505050
Code:
public function imgToArray() {
var c:int;
var rx:int;
var ry:int;
aimage=new Array(imageSize);
for (rx=0; rx<imageWidth; rx++) {
bitmap.lock();
for (ry=0; ry<imageHeight; ry++) {
//aimage[(ry*imageWidth)+rx]=
if (bitmap.getPixel(rx,ry)>sprite.sensibleResult) {
aimage[(ry*imageWidth)+rx]=true;
//bitmap.setPixel(rx,ry,0xFFFFFF);
} else {
aimage[(ry*imageWidth)+rx]=false;
//bitmap.setPixel(rx,ry,0x000000);
}
//trace(aimage[(ry*imageWidth)+rx]);
}
bitmap.unlock();
}
}
I do the reading pretty much exactly in the same way. I don't get the idea of your array but I don't think that changes anything.
One question, what does bitmap.lock() do? Just make sure nothing can access it while you're reading it?
edit: also don't you need to convert the data from getPixel to base16?
Here's my code if you want to compare
PHP Code:
public function ReadBitmap(mapTexture:Texture):void { var bitWidth:int = mapTexture.bitmap.width; var bitHeight:int = mapTexture.bitmap.height;
for (var k:int = 0; k < bitWidth; k++) { for (var l:int = 0; l < bitHeight; l++){ pixelValue = mapTexture.bitmap.getPixel(k, l); pixel = pixelValue.toString(16); setMap(k, l, pixel); } } }
By the way this returns somewhat weird values, ff is fe and it leaves any 0's out if theres nothing before them. But I'm lazy so I haven't figured a way to fix it.
Hatu;
you dont need to use the hex value by using the functions described before, however if you need it for whatever reason all you have to do is to use toString16() in the uint number you got. like this.
Code:
hexNumberString=myPixel.toString(16)
Just remember that "number" is actually a string.
p.s.
just for the record for those who've read this thread thinking Im not using the obvious solution, I dont need a "byteArray" (which I could get with getPixels) I need a bitArray which only has false and true in it, what for? for fast image shape recognition. The problem is the above method is pretty slow about 50 ms for a 320 x 240 image.
Also the reason why Im using a linear Array instead of a multidimensional array is because myArray[320*x+y] is faster to access than myArray[x][y] try it. thats because the memory navigation required to find the address where the value is located is easier for the cpu to calculate one mul and an add instead.
Well, I tried to use the byteArray just to see what happens (and some profiling as well) and the results are amazing, the original code used up to 1000 ms, by using getPixel to read each pixel in the screen, in comparison gePixels for the entire screen took 11 ms! analyzing that however takes 300-400 ms. But it is still twice as fast. Unless I find a faster (and precise) way to analyze the bytearray data, this is the code Im using from now on.
So kids eat your byteArrays they are good for you.
heres the code:
Code:
public function imgToArray() {
var ms:int=getTimer();
var ba:ByteArray;
var rgb:Array=new Array(4);
var counter:int=0;
var pcounter=0;
var myPixel:uint;
var byte:uint;
aimage=new Array(imageSize);
bitmap.lock();
ba=bitmap.getPixels(new Rectangle(0,0,imageWidth,imageHeight));
trace("-----------ImgToArray MS:" + (getTimer() - ms).toString());
ba.position=0;
while (true) {
try {
byte=ba.readUnsignedByte();
rgb[counter]=byte;
counter++
if (counter>3){
myPixel=((rgb[1]<< 16)+(rgb[2]<< 8)+(rgb[3]));
if (myPixel<sprite.sensibleResult) {
aimage[pcounter]=true;
}
else {
aimage[pcounter]=false;
}
pcounter++;
counter=0;
}
} catch (e:EOFError) {
break;
}
}
trace("-----------ImgToArray MS:" + (getTimer() - ms).toString());
}
Nope, wrong again this is even faster, it ticks around 200ms in a crappy machine
Code:
public function imgToArray() {
var c:int;
var rx:int;
var ry:int;
var ms:int=getTimer();
var ba:ByteArray;
var rgb:Array=new Array(4);
var counter:int=0;
var pcounter=0;
var myPixel:uint;
var byte:uint;
var bcounter:int=0
aimage=new Array(imageSize);
bitmap.lock();
ba=bitmap.getPixels(new Rectangle(0,0,imageWidth,imageHeight));
trace("-----------ImgToArray MS:" + (getTimer() - ms).toString());
for (pcounter=0;pcounter<imageSize;pcounter++){
bcounter=pcounter*4
myPixel=((ba[bcounter+1]<< 16)+(ba[bcounter+2]<< 8)+(ba[bcounter+3]));
aimage[pcounter]=myPixel<sprite.sensibleResult;
}
trace("-----------ImgToArray MS:" + (getTimer() - ms).toString());
trace("pix:"+myPixel.toString(16));
}