Date post: | 15-Oct-2015 |
Category: |
Documents |
Upload: | ryan-murray |
View: | 36 times |
Download: | 0 times |
of 15
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 1 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
AS3 TipsAS3 LinksAbout
search...
Jan102010
Bit shifting and masking,bitwise operators in AS 3.Getting Alpha channel outof the color.
In this article I'm going to show how toextract color channels out from the color valueand how to create new colors using bitwiseoperators in Action Script. First there is sometheory with examples and then practising withcoding.
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 2 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
First some theory about the colors:
ARGB colors as 32 bit variables are specifiedby 4 groups of 8 bits each / or 2 hex each:
In binary:
AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB
In hex:
AA RR GG BB
where each group defines intensity of each ofthe colors channels, A is alpha, R is red, G isgreen, B is blue.
FF is full intensity (255), 00 is no color in thechannel (0).White (full intensity on all channels) is in hex:0xFFFFFFFF.Black (no color in any of the Red, Green, andBlue channels) is in hex: 0xFF000000.Full intensity on the alpha channel means noalpha (FF) and no intensity (00) means fullalpha. So a transparent pixel color value is0x00rrggbb.
Everybody use hex as that's the one, which is
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 3 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
easiest to read (use 0x where declaringvariables in hex, ie: var myColor:int =0xAABBCCDD). Although binary representationis very long, we use it to understand howthings work behind the scenes. In decimal therange for each channel is 0 - 255.
Some theory about the bitoperators:
& - bitwise AND operator, used often formasking, works the way that 1 AND 1 gives 1,0 AND 0 gives 0, 1 AND 0 or 0 AND 1 gives 0.
Below example:1010
AND 0111gives 0010
Let's code it:
12345678
var a:int = 10;trace(a.toString(2) + " (bin) | " + a.toString(10) + " (dec)"); var b:int = 7 ;trace(b.toString(2) + " (bin) | " + b.toString(10) + " (dec)"); var c:int = a & b;trace(c.toString(2) + " (bin) | " + c.toString(10) + " (dec)");
Traced results:
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 4 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
a: 1010 (bin) | 10 (dec)b: 111 (bin) | 7 (dec)c = a & b: 10 (bin) | 2 (dec)
| - bitwise OR operator, works as follows, 0OR 0 gives 0, 0 OR 1 or 1 OR 0 gives 1, 1 OR1 gives 1
Below example:1010
OR 0111gives 1111
Let's code it:
12345678
var a:int = 10;trace("a: " + a.toString(2) + " (bin) | " + a.toString(10) + " (dec)"); var b:int = 7 ;trace("b: " + b.toString(2) + " (bin) | " + b.toString(10) + " (dec)"); var c:int = a | b;trace("c = a | b: " + c.toString(2) + " (bin) | " + c.toString(10) + " (dec)");
Traced results:
a: 1010 (bin) | 10 (dec)b: 111 (bin) | 7 (dec)c = a | b: 1111 (bin) | 15 (dec)
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 5 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
>>n or >n - unsigned right shifting by n-bits
Example:
1011 (11 in dec) >> 2 gives 0010 (2 in dec)
1011 (11 in dec) > 2 ;trace("b = a >> 2: " + b.toString(2) + " (bin) | " + b.toString(10) + " (dec)");
Traced results:
a: 1011 (bin) | 11 (dec)b = a >> 2: 10 (bin) | 2 (dec)
Left shifting:
12345
var a:int = 11;trace("a: " + a.toString(2) + " (bin) | " + a.toString(10) + " (dec)"); var b:int = a
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 6 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
Now time for practicing - replacingalpha channel with AND and OR
So now let's try to use what we've just learnedto replace the Alpha part of our color withAlpha from different color.
Let's say I have color named "my color", that Iwant to apply the alpha part from the "othercolor". I'm going to do that in three steps.First I mask out the Alpha part from "mycolor". In the second step I mask out the colorparts from the "other color" leaving only thealpha part. At the last step I will "merge" twovariables creating new color.
"My color" is: 0xEEDDEEEE (hex), the "othercolor" is: 0xABCCDDEE (hex).Let's change representaion to binary to seehow the whole operation looks like.
First let's get rid of the alpha part from "mycolor". To mask it out, we use AND operatorand 32 bit value that has the first part (firstbyte - 8 leading bits) only "0"s
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 7 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
our color: 11101110 11011101 1110111011101110 (bin) 0xEEDDEEEE (hex)mask: 00000000 11111111 1111111111111111 (bin) 0x00FFFFFF (hex)result of AND: 00000000 11011101 1110111011101110 (bin) 0x00DDEEEE (hex)
Now similar thing with the "other color", wemask out everything except the Alpha part:
other color: 10101011 11001100 1101110111101110 (bin) 0xABCCDDEE (hex)mask: 11111111 00000000 0000000000000000 (bin) 0xFF000000 (hex)result of AND: 10101011 00000000 0000000000000000 (bin) 0xAB000000 (hex)
Now let's combine both results using ORoperator:
masked our color: 00000000 1101110111101110 11101110 (bin) 0x00DDEEEE (hex)masked other color: 10101011 0000000000000000 00000000 (bin) 0xAB000000 (hex)result of OR: 10101011 1101110111101110 11101110 (bin) 0xABDDEEEE (hex)
OK, let's code it:
123
var myColor:Number = 0xEEDDEEEE;var otherColor:Number = 0xABCCDDEE;
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 8 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
345678
var resultColor:Number = ((myColor & 0x00FFFFFF) | (otherColor & 0xFF000000)); trace("myColor: " + myColor.toString(2) + " (bin) | " + myColor.toString(16) + " (hex)");trace("newAlphaColor: " + otherColor.toString(2) + " (bin) | " + otherColor.toString(16) + " (hex)");trace("resultColor: " + resultColor.toString(2) + " (bin) | " + resultColor.toString(16) + " (hex)");
And here are traced result:
myColor: 11101110 1101110111101110 11101110 (bin) | eeddeeee (hex)newAlphaColor: 10101011 11001100 1101110111101110 (bin) | abccddee (hex)resultColor: -1010100 0010001000010001 00010010 (bin) | -54221112 (hex)
Looking at the results, we notice that this isnot what we actually expected... It looks likenegative value. Why?Let's amend last line in the code to traceresults as unsigned int:
1 trace("resultColor: " + uint(resultColor).toString(2) + " (bin) | " + uint(resultColor).toString(16) + " (hex)");
and now the result is correct:
resultColor: 10101011 11011101 1110111011101110 (bin) | abddeeee (hex)
Action Script data types like int or Number arestored the way that the first bit (the leadingbit) indicates whether value is positive ornegative. To read more about negative intplease click here. There are no negative values
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 9 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
in the colors, so we actually should be usingunsigned int (uint) rather than int (or Number- actually this data type should be rather usedfor values bigger than 32 bits due to theperformance reasons).
Extracting individual channels withbit shifting
We can use bit shifting as a method ofextracting individual color channels: first bymoving necessary bits to the right and thenmasking out unnecessary values if there areany. Let's code it:
123456789
101112
var myColor:uint = 0xABCCDDEE; var myAlpha:uint = myColor >> 24;var myRed:uint = (myColor >> 16) & 0xFF;var myGreen:uint = (myColor >> 8) & 0xFF;var myBlue:uint = myColor & 0x000000FF; trace("myColor:" + myColor.toString(2) + " (bin) | " + myColor.toString(16) + " (hex)");trace("Alpha: " + myAlpha.toString(2) + " (bin) | " + myAlpha.toString(16) + " (hex)");trace("Red: " + myRed.toString(2) + " (bin) | " + myRed.toString(16) + " (hex)");trace("Green: " + myGreen.toString(2) + " (bin) | " + myGreen.toString(16) + " (hex)");trace("Blue: " + myBlue.toString(2) + " (bin) | " + myBlue.toString(16) + " (hex)");
And the result is:
myColor: 10101011 11001100 1101110111101110 (bin) | abccddee (hex)Alpha: 11111111 11111111 1111111110101011 (bin) | ffffffab (hex)
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 10 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
Red: 11001100 (bin) | cc(hex)Green: 11011101(bin) | dd (hex)Blue: 11101110 (bin) | ee (hex)
Hmm, the red, green, blue are as expectedbut what has happened to our Alpha channel,we are expecting just AB and we got series of"1" in front of AB. This is again related to theway how the data types are stored in ActionScript. This will happen every time when youwill try to right-shift 32 bit values. It will befine for 24 bit (RGB). First hex digit of ourcolor is A which is 1010 in binary. The first bitis "1" what means this is a negative value.You may think, ok but we are using unsignedint... Well there is another way of right-shiftingbits: >>>n shifts n bits to the right withoutcaring about sign. It's called unsigned rightshift.
So remember:>> - pads with 1 or 0, if negative or positiverespectively>>> - pads with 0 no matter what
Let's see a difference on example below:
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 11 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
This was positive value, missing bits on theleft were replaced with zeros.01010101 00000000 00000000 00000000 >>2 = 00010101
This was negative value, missing bits on theleft were replaced with ones. This is again theway how Flash works with signed values. Readmore here.10101010 00000000 00000000 00000000 >>2 = 11101010
01010101 00000000 00000000 00000000 >>>2 = 00010101
No matter what is the leading bit, one or zero,unsigned right shifting replace missing bitswith zeros.10101010 00000000 00000000 00000000 >>>2 = 00101010
So let's modify our code and see what we willget:
123456789
101112
var myColor:uint = 0xABCCDDEE; var myAlpha:uint = myColor >>> 24;var myRed:uint = (myColor >> 16) & 0xFF;var myGreen:uint = (myColor >> 8) & 0xFF;var myBlue:uint = myColor & 0x000000FF; trace("myColor:" + myColor.toString(2) + " (bin) | " + myColor.toString(16) + " (hex)");trace("Alpha: " + myAlpha.toString(2) + " (bin) | " + myAlpha.toString(16) + " (hex)");trace("Red: " + myRed.toString(2) + " (bin) | " + myRed.toString(16) + " (hex)");trace("Green: " + myGreen.toString(2) + " (bin) | " + myGreen.toString(16) + " (hex)");trace("Blue: " + myBlue.toString(2) + " (bin) | " + myBlue.toString(16) + " (hex)");
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 12 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
This time results are fine:
myColor: 10101011 11001100 1101110111101110 (bin) | abccddee (hex)Alpha: 10101011 (bin) | ab (hex)Red: 11001100 (bin) | cc (hex)Green: 11011101(bin) | dd (hex)Blue: 11101110 (bin) | ee (hex)
How is negative integer "stored" inmemory?
You won't find much literature explaining howthe data typs including negative integer arestored in memory. I had troublesunderstanding what's going on when shiftingbits right in 32 bit variables. I got some helpfrom Lordofduct on actionscript.org, who hasshed some more light on that subject (link tothat thread at the end of this article).
I'm going to quote him from the thread on theforum:
~ - NOT - this is not with only one value. A 1is placed where a zero is, a 0 where a one is.
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 13 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
This is called the 'binary inverse' of the value.The binary inverse of N bits in length of avalue is the same number that needs to besubtracted from (2^N) - 1 to make thenegative value of said value. That is why anegative int is just the NOT form of thepositive value. You can try it, take a uint, NOTit, and then cast it as an int and you'll havethat value negative - 1.
trace( uint( ~3 ) );//you get -4... -(3 + 1)
or as such:
trace( uint.MAX_VALUE - uint(~3) );//you get3
I bring this up because this is how negativeintegers are stored. It's 1 followed by the 31bits that represent the inverse of the absolutevalue. Anways so you can see the operand inaction:
~1010 == 0101
The NOT of any positive value equals the -(value+1)
Example: What is NOT of 15?
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 14 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
JComments
0000 1111 (bin) == 15 (dec)1111 0000 (bin) == -16 (dec)
1234
var pos:int = 15;var neg:int = ~pos;trace("Positive value: " + pos + " is in binary: " + pos.toString(2));trace("Negative value: " + neg + " is in binary: " + uint(neg).toString(2));
Gives as a result:
Positive value: 15 is in binary: 1111Negative value: -16 is in binary: 1111111111111111 11111111 11110000
So now you know how negative integers arestored in memory... but if you still wonder -why...well it makes sense? For furtherexplanation visit a thread with discussionhttp://www.actionscript.org/forums/showthread.php3?t=190086 and read the explanation withexamples from Lordofduct.
Add comment
AS3 Tips
List of alltips
10/23/10 10:14 PMBit shifting and masking, bitwise operators in AS 3. Getting Alpha channel out of the color.
Page 15 of 15http://sierakowski.eu/list-of-tips/37-bit-shifting-and-masking-bitwise-operators-in-as-3-getting-alpha-channel-out-of-the-color.html
Copyright 2010 sierakowski.eu | Wojciech Sierakowski - TheActionScript 3 Developer Blog. All Rights Reserved.