読者です 読者をやめる 読者になる 読者になる

UIColorとビット演算(& / >>)

iOS 基礎技術

今更感のある内容ですが、ちゃんと理解できていなかったので。

UIColorと16進数カラーコード

業務でiOSアプリを開発していると、デザイナーから16進数カラーコードが送られてくることが多々あります。
しかし、UIColorは16進数カラーコードに対応しておらず、かといって毎回変換するのも面倒。 というわけで、以下のメソッドにそのまま16進数カラーコードを渡してUIColorを取得する、ということをよくやるのですが、 内容をしっかり理解できていなかったので、基礎固めとして調べてみました。

extension UIColor {
    class func colorWithRGBValue(rgbValue: UInt32, alpha: CGFloat) -> UIColor {
        return UIColor(
            red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
            green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
            blue: CGFloat((rgbValue & 0x0000FF) >> 0) / 255.0,
            alpha: alpha)
    }
}

rgbValueの型になぜUInt32を使うのか

そもそも、なぜrgbValue(例: 0x0bbed3)の型にUInt32を指定しているのでしょうか。
16進数のカラーコード(RGBA)では、R/G/B/Aがそれぞれ0...255の256通りの値を持ちます。 256 = 28なので、RGBAの表現には、 8bit * 4で32bit必要、ということになります。 そのため、UInt32を使っています。

&(ビットマスク)

(rgbValue & 0xFF0000)の部分はどのような意味でしょうか。
& は、ビットマスクを呼ばれる処理を実行し、必要な場所以外のビットを0で覆います。
それぞれの処理をビットマスクが理解しやすい形で書くと、
(0x0bbed3 & 0xFF0000)は、

16進数 R G B
0x0bbed3 0000 1011 1011 1110 1101 0011
0xFF0000 1111 1111 0000 0000 0000 0000
0x0b0000 0000 1011 0000 0000 0000 0000

(0x0bbed3 & 0x00FF00)は、

16進数 R G B
0x0bbed3 0000 1011 1011 1110 1101 0011
0x00FF00 0000 0000 1111 1111 0000 0000
0x00be00 0000 0000 1011 1110 0000 0000

(0x0bbed3 & 0x0000FF)は、

16進数 R G B
0x0bbed3 0000 1011 1011 1110 1101 0011
0x0000FF 0000 0000 0000 0000 1111 1111
0x0000d3 0000 0000 0000 0000 1101 0011

となり、元の16進数のR/G/Bそれぞれの値のみを含む16進数が取得できることがわかると思います。

>>(ビットシフト)

最後に >> でビットシフトを行います。
>> 16 では、16bit分、
>> 8 では、8bit分、
>> 0 では、0bit分、ビットシフトが行われるため、

0x0b0000(0000 1011 0000 0000 0000 0000)
0x00000b(0000 0000 0000 0000 0000 1011)に、
0x00be00(0000 0000 1011 1110 0000 0000)
0x0000be(0000 0000 0000 0000 1011 1110 )に、
0x0000d3(0000 0000 0000 0000 1101 0011)
0x0000d3(0000 0000 0000 0000 1101 0011)のままとなります。


これで、計算できる形となるため、元の式に代入して計算完了となります。

やってみると、簡単でしたね。

参考