views:

242

answers:

4

Question: The below code crashes flash... Why?

The crash causing lines seem to be


//var uiColor:uint = bmpd.getPixel(i,j);
var uiColor:uint = bmpd.getPixel32(i,j);
trace("Color: "+ uiColor);

I am trying to take a snapshot of a movieclip and iterate through all pixels in the image and get the pixel's color.

import flash.display.BitmapData;
import flash.geom.*;


function takeSnapshot(mc:MovieClip):BitmapData 
{
var sp:BitmapData = new BitmapData(mc.width, mc.height, true, 0x000000);
sp.draw(mc, new Matrix(), new ColorTransform(), "normal");
return sp;
}

var mcMyClip:MovieClip=new MovieClip()
var xxx:cMovieClipLoader=new cMovieClipLoader(); 

xxx.LoadImageAbsSize(mcMyClip,"http://localhost/flash/images/picture.gif", 500,500)

//this.addChild(mcMyClip);

function WhenImageIsLoaded()
{
var bmpd:BitmapData=takeSnapshot(mcMyClip);

var i,j:uint;

for(i=0; i < bmpd.width;++i)
{
    for(j=0; j < bmpd.height;++j)
    {
        //var uiColor:uint = bmpd.getPixel(i,j);
        var uiColor:uint = bmpd.getPixel32(i,j);
        trace("Color: "+ uiColor);
    }
}


var myBitmap:Bitmap = new Bitmap(bmpd);



this.addChild(myBitmap);
}

setTimeout(WhenImageIsLoaded,1000);
A: 

No idea if it's as simple as this, but have you tried with bmdp.width - 1 in the for loop condition?

debu
nope, < width is correct
Quandary
A: 

The constructor for BitMapData takes as its 4th arg an ARGB color value (e.g., 0x00000000 -- eight digits), not an RGB value (e.g., 0x000000 -- six digits). Maybe that's your problem: you haven't supplied the Alpha channel value.

Robusto
Appending 0s to 0x0 doesn't change its value; it will still be 0.
TC
@TC: lol, so true.
Quandary
+1  A: 

Does the getPixel call work and not the getPixel32? What's the sandbox situation like? Do you have enough "permission" to access the bitmap as data? Perhaps you need a LoaderContext to pass to the Loader that is loading the image? Have you traced/debugged out the Bitmap Data size to see how big it actually is?

Typeoneerror
+1  A: 

Solved.

There were 3 problems at once:
1. It has transparency, so only GetPixel32 works
2. mcMyClip.width & height returns a wrong value mcMyClip.getBounds(mcMyClip).width & height returns the correct value (because the original movieclip is a resized one)
3. 800x600 picture = 480'000 points * 1 trace messages in the blink of a second, which is the cause for the crash (might actually be a Vista problem...)

Quandary
For #0, 0x000000 is exactly the same as 0x0000000. Also equivalent: 0x0, 0, (24/6-9+5). For #1, you can call getPixel on a non-transparent BitmapData, it just doesn't give you the alpha data.
aaaidan
For #2, you can pass mcMyClip.transform.matrix for the matrix parameter in the BitmapData.draw() call.
aaaidan
For #3, try if (i%16==0 } // traces only every 256th pixel
aaaidan
@aaaidan: I found out some time ago: The MovieClip I work with only has Alpha data (no colors, everything is 0,0,0, difference only in the alpha value) !
Quandary
Haha ... awesome.
aaaidan