본문 바로가기

프로그래밍/Etc

color 추출

비트 연산(Bitwise operation)은 한 개 혹은 두 개의 이진수에 대해 비트 단위로 적용되는 연산입니다.

사람한테는 10진수가 익숙하긴 한데 컴퓨터는 2진수가 편하다는군요.

2진수 100101을 10진수로 표시하면 아래와 같습니다.

100101 = (1 * 25) + (0 * 24) + (0 * 23) + (1 * 22) + (0 * 21) + (1 * 20) = 32 + 4 + 1 = 37

 

컬러조작에서 자주 사용되기 때문에 컬러 값을 조작하는 것으로 비트연산자를 설명할까합니다.

아래 표를 보면 16진수 0은 2진수로 0입니다. 그리고 16진수 F는 2진수로 1111입니다. 잘 기억해주세요.

10진수

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16진수

0

1

2

3

4

5

6

7

8

9

A

B

C

D

E

F

2진수

0000

0001

0010

0011

0100

0101

0110

0111

1000

1001

1010

1011

1100

1101

1110

1111

 

쉬프트 연산자

16진수 0xFF0000은 빨간색입니다. 2진수로는 아래와 같습니다.

1 

1 

1 

1 

1 

1 

1 

1 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

이 0xFF0000을 오른쪽으로 8칸 보내면

0xFF0000 >> 8

               

1 

1 

1 

1 

1 

1 

1 

1 

0 

0 

0 

0 

0 

0 

0 

0 

0xFF00이 됩니다. 그럼 초록색이 되는군요. 다시한번 >> 8을 하면 이제 파란색이 되겠군요.

쉬프트 연산은 이처럼 2진수의 자리수를 이동시키는 것입니다.

 

AND 연산자

0xF845A3 이란 값은 분홍빛입니다.

이 색에서 RGB값을 추출해 내보려고 합니다.

 

0xF845A3을 2진수 테이블을 만들어 보면 아래와 같습니다.

1 

1 

1 

1 

1 

0 

0 

0 

0 

1 

0 

0 

0 

1 

0 

1 

1 

0 

1 

0 

0 

0 

1 

1 

 

먼저 R(red)를 먼저 추출해 봅시다. 오른쪽 쉬프트 16번 하면 되겠군요.

0xF845A3 >> 16 간단하네요.

1 

1 

1 

1 

1 

0 

0 

0 

 

이제 G(green)을 해봅시다. 8칸을 오른쪽으로 보내고 빨간 녀석을 없애버려야 하는데… 흠…이제 AND연산자의 성질이 필요해지네요.

AND 연산은 두 값의 각 자릿수를 비교해, 두 값 모두에 1이 있을 때에만 1을, 나머지 경우에는 0을 계산합니다.

0 & 0 = 0

0 & 1 = 0

1 & 0 = 0

1 & 1 = 1

 

따라서 0xF845A3을 8칸 보낸 0xF845 에 0x00FF(=0xFF)를 AND 연산하면

 

 

& 

0000000011111111

1111100001000101

 

0000000001000101 

 

0과는 무조건 0이되기 때문에 1000101만 남는군요. 1000101은 우리가 추출하려던 green영역 값 0x45를 얻었습니다.

 

0 

1 

0 

0 

0 

1 

0 

1 

 

이제 남은 파란색영역도 그린과 마찬가지 입니다. 이번에는 시프트가 필요없겠네요.

그냥 0xF845A3에 0x0000FF(=0xFF)만 AND 연산 해주면 되겠습니다.

 

1 

0 

1 

0 

0 

0 

1 

1 

 

var a : int= 0xF845A3;

trace((a>>16).toString(16));    //f8

trace((a>>8&0xFF).toString(16));    //45

trace((a&0xFF).toString(16));     //a3

 

OR 연산자

이제 어렵게 나눈 R, G, B를 다시 합치려 합니다.

16칸을 쉼없이 달려온 R을 다시 자기 자리로 떠나 보내야 하는군요.

쉽죠 뭐 왼쪽으로 16번 시프트해주기만 하면되죠. G는 8번이었죠? B는 그대로 있으면 됩니다.

 

OR연산자는 AND연산자와 달리 참(1)하나라도 있으면 참이라고 인정해주는 아주 착한 녀석입니다. 따라서 OR 연산은 두 값의 각 자릿수를 비교해, 둘 중 하나라도 1이 있다면 1을, 아니면 0을 계산합니다.

 

0 | 0 = 0

0 | 1 = 1

1 | 0 = 1

1 | 1 = 1

 

1 

1 

1 

1 

1 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0 

0

0

0

0

0

0 

0 

0 

0 

0 

0 

0 

0 

0 

1 

0 

0 

0 

1 

0 

1 

0 

0 

0

0

0

0

0

0

0 

0 

0 

0 

0 

0 

0 

0 

0

0

0

0

0

0

0

0

1 

0 

1 

0 

0 

0 

1 

1 

 

따라서 위치이동시킨 R, G, B를 OR연산을 하면 원래의 0xF845A3로 돌아오게 됩니다.

1 

1 

1 

1

1 

0 

0 

0 

0 

1 

0 

0 

0 

1 

0 

1 

1 

0 

1 

0 

0 

0 

1 

1 

 

 

Adobe의 devnet에 좋은 기사가 있습니다.

http://www.adobe.com/devnet/flash/articles/bitwise_operators.html

32bit unsigned bitwise shift 연산자 관련한 글

http://www.bit-101.com/blog/?p=1054