View comments | RSS feed

threshold (BitmapData.threshold method)

public threshold(sourceBitmap:BitmapData, sourceRect:Rectangle, destPoint:Point, operation:String, threshold:Number, [color:Number], [mask:Number], [copySource:Boolean]) : Number

Tests pixel values in an image against a specified threshold and sets pixels that pass the test to new color values. Using the threshold() method, you can isolate and replace color ranges in an image and perform other logical operations on image pixels.

The threshold test's logic is as follows:

if ((pixelValue & mask) operation (threshold & mask)) then

    set pixel to color

 else

    if (copySource) then

       set pixel to corresponding pixel value from sourceBitmap

The operation parameter specifies the comparison operator to use for the threshold test. For example, by using "==", you can isolate a specific color value in an image. Or by using {operation: "<", mask: 0xFF000000, threshold: 0x7f000000, color: 0x00000000}, you can set all destination pixels to be fully transparent when the source image pixel's alpha is less than 0x7F. You can use this technique for animated transitions and other effects.

Availability: ActionScript 1.0; Flash Player 8

Parameters

sourceBitmap:flash.display.BitmapData - The input bitmap image to use. The source image can be a different BitmapData object or it can refer to the current BitmapData instance.

sourceRect:flash.geom.Rectangle - A rectangle that defnes the area of the source image to use as input.

destPoint:flash.geom.Point - The point within the destination image (the current BitmapData instance) that corresponds to upper-left corner of the source rectangle.

operation:String - One of the following comparison operators, passed as a String: "<", "<=", ">", ">=", "==", "!="

threshold:Number - The value that each pixel is tested against to see if it meets or exceeds the threshhold.

color:Number [optional] - The color value that a pixel is set to if the threshold test succeeds. The default is 0x00000000.

mask:Number [optional] - The mask to use to isolate a color component. The default value is 0xFFFFFFFF.

copySource:Boolean [optional] - A Boolean value. If the value is true, pixel values from the source image are copied to the destination when the threshold test fails. If the value is false, the source image is not copied when the threshold test fails. The default value is false.

Returns

Number - The number of pixels that were changed.

Example

The following example shows how to change the color value of pixels whose color value is greater than or equal to a certain threshold.

import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Point;

var myBitmapData:BitmapData = new BitmapData(100, 80, false, 0x00CCCCCC);

var mc:MovieClip = this.createEmptyMovieClip("mc", this.getNextHighestDepth());
mc.attachBitmap(myBitmapData, this.getNextHighestDepth());

myBitmapData.fillRect(new Rectangle(0, 0, 50, 80), 0x00FF0000);

mc.onPress = function() {
    myBitmapData.threshold(myBitmapData, new Rectangle(0, 0, 100, 40), new Point(0, 0), ">=", 0x00CCCCCC, 0x000000FF, 0x00FF0000, false);
}

Version 8

Comments


webweber@bluewin.ch said on Sep 21, 2005 at 1:35 AM :
I feel that the explanation is missing an important element: what is tested against, what is compared?
Or, in other words, what exactly are ' pixel values '?
It can't be the 'raw' ARGB numbers:

import flash.display.BitmapData;
pixelColor = 0x000000FF;
thresholdColor = 0x0000FF00;
newColor = 0x00FF0000;
this.createEmptyMovieClip('clip', 1);
bd = new BitmapData(100,100,false,pixelColor);
clip.attachBitmap(bd, 1);
bd.threshold(bd, bd.rectangle, bd.rectangle.topLeft, '>', thresholdColor, newColor);

0x000000FF is not greater than 0x0000FF00 and still the new color is applied.

So what exactly is tested? Brightness? Something else? How would the analoguous AS function look like?
Without this information the results of the threshold() method are pretty unpredictable.

And more a formal comment:
> {operation: "<", mask: 0xFF000000, threshold: 0x7f000000, color: 0x00000000}
seems to suggest that there is an alternative way of passing the arguments, not as a comma delimeted list, but as an object. But this is not really a viable alternative?

Cheers!
Francis Cheng said on Sep 21, 2005 at 10:17 AM :
Thanks for the post. I can see how this can be confusing. The simple answer is that you need to set your mask parameter to compare colors only, so your call to threshold() should be:

bd.threshold(bd, bd.rectangle, bd.rectangle.topLeft, '>', thresholdColor, newColor, 0x00FFFFFF);

Here's why: the issue is the interaction between the BitmapData constructor and the threshold() method. When you created your BitmapData object with these lines:

pixelColor = 0x000000FF;
bd = new BitmapData(100,100,false,pixelColor);

You only thought you were setting the ARGB value to 0x000000FF. In fact, the BitmapData constructor disregards your alpha value if the third parameter (transparency) is set to false, as it is in your code. This means that the BitmapData object you created is actually opaque, and has an ARGB value of 0xFF0000FF. So when you call threshold(), it looks like you are comparing "0x000000FF > 0x0000FF00" when in fact you are comparing "0xFF0000FF > 0x0000FF00".

You probably want an alpha value of FF anyway, because if you did change the transparency parameter to true, your SWF would just be blank, since the alpha value of 00 would make your square invisible. That's why the easiest fix is to use the mask. Otherwise, you'd have to change all your color values so that they start with 0xFF.

Regarding your format comment about the object-like syntax, you are correct that you can't pass an object--that was just a handy way to express a subset of parameter values. We should have used different syntax.
webweber@bluewin.ch said on Sep 22, 2005 at 1:54 AM :
Thanks Francis, this makes perfect sense now.

So it's basically the third parameter of the BitmapData constructor - the transparency switch - that bit me - it also has to be set to true to get the 'fully transparent' example working.
Actually I had it set to false because I copied above code sample -

I would suggest to change it accordingly, changing the switch from false to true and make the alpha chanels FF:

import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Point;

var myBitmapData:BitmapData = new BitmapData(100, 80, true, 0xFFCCCCCC);

var mc:MovieClip = this.createEmptyMovieClip("mc", this.getNextHighestDepth());
mc.attachBitmap(myBitmapData, this.getNextHighestDepth());

myBitmapData.fillRect(new Rectangle(0, 0, 50, 80), 0xFFFF0000);

mc.onPress = function() {
myBitmapData.threshold(myBitmapData, new Rectangle(0, 0, 100, 40), new Point(0, 0), ">=", 0xFFCCCCCC, 0xFF0000FF, 0xFFFF0000, false);
}

This should be a less problematic base for further experimentation.

Cheers!
Andreas Weber
imd_engineer said on Sep 23, 2005 at 5:35 PM :
Hey Andreas,

Thanks so much for your feedback on this example!

We have updated the source to include your revisions.
Jackie_2004 said on Nov 14, 2005 at 8:50 PM :
hi! i was wondering if there is a way to DELETE the pixels that are background of the BitmapData result in order to set a mask to another image... i tried it but when i set set mask everytings is masked and i want just some parts of the result BitmapData
No screen name said on Mar 13, 2007 at 4:26 AM :
What you need to do is cache the movieclip to be masked and the mask as bitmaps. i.e. mc.cacheAsBitmap = true. Do this before doing a setmask. Also, make sure your bitmapdata is set for transparency.

 

RSS feed | Send me an e-mail when comments are added to this page | Comment Report

Current page: http://livedocs.adobe.com/flash/8/main/00001969.html