顏色表示和位操作
今天在看一個Android開源代碼的時候看到中間有這么一句:
mTextView.setBackgroundColor(alpha << 24 | (0xbbffbb)); mTextView.setTextColor(alpha << 24 | (0x000000));
其中mTextView是TextView類的對象,而alpha是一個0到255之間的int值。
雖然知道是設置顏色,但是這種寫法還是引起了我的好奇心。
怎么又是位移操作又是與運算的。
搜索一下,找到一份資料:http://m.oschina.net/blog/104123
整理轉述得此文。
首先科普一下顏色的表示:
首先,顏色各個分量一般是以每8位為一個單位。
8位,8bit,即一個字節,10進制數的取值范圍是0~255,一般用16進制表示,0x開頭,取值范圍是0x00到0xFF(不區分大小寫)。
顏色一般有24位和32位兩種表示方法。
24位顏色:每8位表示RGB中的一個分量。RGB顏色分量的值越大的時候最終顏色越偏向於這個顏色。
32位顏色:除了每8位表示RGB中的一個分量,還有一個8位用於表示透明度,表示為ARGB形式。
A即alpha值,alpha值為0時顏色為透明,alpha值為最大值時顏色為完全不透明,即可完全覆蓋處於它下面的其他顏色,無其他顏色可以透過它而顯示出來。

那么位移操作是怎么回事呢?
如圖:

表示顏色分量的數要想轉化成一個整個的顏色,就必須和其他的分量組合,每個分量放在自己應當處於的位置,就應該進行位移操作。
當然我開始的時候還小迷惑了一下這個資料中給出的例子:http://m.oschina.net/blog/104123,
如果顏色值都是34,23,88等兩位十進制數,而它所說的轉換居然也就是把數字直接放過去了,那0到255的數字,255咋辦?三位數呢?
后來想了一下,作者的圖是對的,但是文字配的有點問題。
圖中的顏色值34,23和88都是十六進制表示的,所以移位操作的時候可以直接移動位置表示。
移位后就是整體移動相應的位數,一個字母代表四位。
R移動16位,G移動8位,B不需要移動。
如果有A值,則A需要向左移動24位。
需要注意的是,不管是用什么進制表示,十進制還是十六進制還是二進制,位移操作都是二進制范疇的。
為什么說原作者有點小錯誤呢?
十進制的34,用十六進制表示是0x22。
如果是十進制R34,G23,B88。移位操作后,得到的顏色數值應該是0x221758。
反向的轉換:從顏色中提取分量
反向的轉換則是右移。
知道一個顏色整體值,想提取某一個顏色分量,方法就是向右移動相應的位數,然后做一個與運算,與0xFF做與運算可以提取最低的兩位。
這一步參考資料說得很明白:
直接把例子搬過來:
現在我們知道了rgb的16進制值,那反過來呢?如果我們知道了一個顏色值,如何反向求解rgb值呢?
var color:uint = 0x342388; var r:uint = color >> 16;//右移16位,把2388移出,取0x34 var g:uint = color >> 8 & 0xff;//右移8位,把88移出,得0x3423,與0xff按位與操作,得0x23 var b:uint = color & 0xff;//得到0x88
我們再來看看32位的:
var color:uint = 0xff342388; var a:uint = color >>> 24 //注意這里是>>>,無符號右移位操作,右移24位,把342388移出,得到0xff var r:uint = color >> 16 & 0xff;//右移16位,把2388移出,取0x34 var g:uint = color >> 8 & 0xff;//右移8位,把88移出,得0x3423,與0xff按位與操作,得0x23 var b:uint = color & 0xff;//得到0x88
參考資料:
位操作也瘋狂:http://m.oschina.net/blog/104123
PS,推薦在線顏色選擇器:http://coolshell.cn/articles/3314.html
PPS:FireFox上也有插件(ColorZilla),可以直接從網頁上提取顏色,獲取其顏色值。
