+ All Categories
Home > Documents > as3_bitshiftingColor

as3_bitshiftingColor

Date post: 15-Oct-2015
Category:
Upload: ryan-murray
View: 36 times
Download: 0 times
Share this document with a friend
Description:
bitshift

of 15

Transcript
  • 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.