Home > ActionScript 2.0 | ActionScript 3.0 > AS3.0 16進数の色分解ではまった事

AS3.0 16進数の色分解ではまった事

Flashで何らかの色を扱うときに
0xff00ff のような16進数表記をすることがあります。

ここからRGBの値を抜き取りたいと思って
ビット演算して抜いてたら、おかしな事になったので
今日はそのお話をしようと思います。

16進数で表記された色情報は

0xRRGGBB ( R=赤, G=緑, B=青 )

のように記述します。
ここから各部分の値を抜き出す事をしたいわけです。
そんな時はビット演算して抜き出すと簡単に出来たりします。
// 色を定義.
var color = 0xff62f0;
// 赤を抜き出す.
var r = ( color & 0xff0000 ) >> 16;
// 緑を抜き出す.
var g = ( color & 0xff00 ) >> 8;
// 青を抜き出す.
var b = ( color & 0xff );

こうやります。つまり、赤を抜きたい場合
0xff62f0 と 0xff0000 でAND演算を行ってから、右シフトしてあげることで
0x0000ff となり、赤色部分が抽出できるというわけです。
同様に緑と青も、0x000062、0x0000f0、にしてあげることで抽出が可能です。

(゜Д゜ )?な方もいらっしゃると思うので
これらの処理の説明を一番最後に設けてあります。
もしわからない方は、そちらをご覧下さい。(まあそこ読んで解るかは不明)

ここまでは、まあ良かったのです。
しかし、これにアルファが絡んでくると、ちょっと挙動があやしくなります。
アルファが入ってくると、表記は

0xAARRGGBB ( A=アルファ, R=赤, G=緑, B=青 )

となり、最大値 0xffffffff は 4294967295 と、int型では表記しきれなくなります。
(int型の有効範囲は 2,147,483,648 ~ 2,147,483,647 なため)

この桁数で記述された色情報からアルファとRGB各色を抜き出すときには
int型を使うと意図しない数値になったりするので(マイナスとか)
uintを使って以下のようにして抽出を行いました。
// 色を定義.
var color:uint = 0xf0ff62f0;
// アルファを抜き出す
var a:uint = ( color & 0xff000000 ) >> 24;
// 赤を抜き出す.
var r:uint = ( color & 0xff0000 ) >> 16;
// 緑を抜き出す.
var g:uint = ( color & 0xff00 ) >> 8;
// 青を抜き出す.
var b:uint = ( color & 0xff );
するとなぜか、アルファの値が 4294967280 になってしまいます。
RGBの値に関しては全く問題がありません。
なんでやねん・・・と思ったのですが、なんかこうやったらうまく行きました。
// 色を定義.
var color:uint = 0xf0ff62f0;
// アルファを抜き出す
var a:uint = ( _color >> 24 ) & 0xff
これで、aの値は240と意図した通りになります。
まあ要するに、先に右シフトしてからAND演算すればOKみたいな?
これってビット演算系では正しい動きなんでしょうか?だれか教えて下さい・・・

とりあえず似たようなことで躓いている方(いるのか?)
ARGB値抜く時(特にアルファ抜く時)は、シフトを先に行う事をお勧めします。

今日はこの辺で。


処理の説明


AND演算だ、シフトだといった処理がわからない方のために
簡単に書く処理を説明します。

AND演算やシフトといった処理は基本的にビットという考え方で使われます。
ビットとは簡単に言えば、二進数で表された数値の事です。
0xffff00と0xff0000をビットで書くと以下のようになります。
(解りやすくするため8ビットごとに空白いれてます)

・0xffff00
11111111 11111111 00000000
・0xff0000
11111111 00000000 00000000

AND演算とはこのような二つのビットを比べて
1と1ならば1、1と0ならば0、0と0ならば0とする処理の事です。
つまりは以下のような処理になります。

11010011 10111111 01001000
11111111 01001100 00000000

11010011 00001100 00000000

したがって、0xffff00と0xff0000のAND演算は以下のようになります。

11111111 00000000 00000000
11111111 00000000 00000000

11111111 00000000 00000000

つまり、赤色を示している部分以外を0にしてしまうことで
赤の部分だけ残すという処理になるわけです。

しかしこのままでは 0xff0000 という値のままなので
数値的には 16711680 という巨大な数値になってしまいます。
なので、右に16ビットシフトしてあげるという事が必要です。
右にシフトとは、各数値を右に一つずらし
はみ出た一番右の数値を一番左に移動する処理のことです。
つまりは以下のような処理になります。

11111111 11111111 00000000

01111111 11111111 10000000

つまり、右に16ビットシフトするということは

11111111 00000000 00000000

00000000 00000000 11111111

となり、数値的には255となります。これで取りたかった赤の値になりました。

同じように緑は 0x00ff00 ( 0xff00 でもよい)でAND演算して右に8ビットシフト
青は 0x0000ff ( 0xff でもよい)でAND演算してあげれば抽出することが出来ます。

Comments:3

Comment Form

コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。

kkanda 2008年4月 3日 00:43

> するとなぜか、アルファの値が 4294967280 になってしまいます。
colorの値の最上位ビットが1なので右シフトした場合に、最上位ビットに1が入ってきます。
そのため、color >> 24とすると上位24ビットが1で埋まっている状態になります。

余談ですが、下記のコードを実行すればアルファ値が下位8ビットに正しくセットされていることが確認できます。

var a:uint = ( color & 0xff000000 ) >> 24;
trace(a & 0xff); // 240が出力される

kawakita 2008年4月 3日 02:31

>kkanda様
なるほど!そういうことでしたか。
ビット演算などはあまり使わない人間なので
そのあたりの仕組みに気づきませんでした・・・

明日にでもそのあたりをいじってみて
いろいろと試してみようと思います。
勉強になりました。ありがとうございました。

munegon 2008年7月12日 23:32

はじめまして

アルファ抜くだけなら、実はこんなやり方があります。
trace( color >>> 24 );

あまり使われない演算子なんですけどね。

Trackbacks:0

TrackBack URL for this entry
http://blog.flair4.jp/mt/mt-tb.cgi/28
Listed below are links to weblogs that reference
AS3.0 16進数の色分解ではまった事 from flair4 blog

Home > ActionScript 2.0 | ActionScript 3.0 > AS3.0 16進数の色分解ではまった事

Search
Feeds

Return to page top