概要
カラーチャンネルをコピーしてみましょう。
ARGBのA, R, G, B、一つ一つのことをチャンネルといいます。
BitmapData#copyChannel()を使用するとチャンネルごとに分けて転送することが可能です。
BitmapData#copyChannel()を使用するとチャンネルごとに分けて転送することが可能です。
例えば、
- 元BitmapDataの青色を、コピー先BitmapDataの青色にコピー
- 元BitmapDataの赤色を、コピー先BitmapDataの緑色にコピー
という風な事が出来ます。
プログラム
対象画像の読み込み方法は、画像処理用のテンプレートを参照してください。
まずは、BitmapData#copyChannel()の使い方を説明します。
書き方としては、コピー先BitmapData.copyChannel(コピー元BitmapData)になります。
第一引数
- sourceBitmapData:BitmapData
- チャンネルを取得する対象のBitmapDataを指定します。
dest.copyChannel(srcbd, ...続く
チャンネルのコピー元BitmapDataを指定します。
copyChannel()はあくまでも「コピーするだけ」なので元BitmapDataの中身が切り取られたりすることはありません。
copyChannel()はあくまでも「コピーするだけ」なので元BitmapDataの中身が切り取られたりすることはありません。
第二引数
- sourceRect:Rectangle
- 元のBitmapDataのどの部分をコピーするかをRectangleクラスで指定します。
- Rectangleクラスに関しては、Rectangleクラスを使用するを参照してください。
dest.copyChannel(srcbd, srcbd.rect, ...続く
BitmapData#rectプロパティで(0, 0, width, height)が取得できるのでrectを指定してあげましょう。
第三引数
- destPoint:Point
- コピー元のチャンネルをコピー先のどこに配置するかをPointクラスで指定します。
- Pointクラスに関しては、Pointクラスを利用するを参照してください。
dest.copyChannel(srcbd, srcbd.rect, new Point(), ...続く
コピー先の左上(0, 0)に配置したいのでnew Point()を指定します。new Point(0, 0)のように0を入れても構いません。
第四引数
- sourceChannel:uint
- どのチャンネル(色)をコピーするかを指定します。
各チャンネルには番号が割り振られていて、
- アルファ - 8 もしくは BitmapDataChannel.ALPHA
- 赤 - 4 もしくは BitmapDataChannel.RED
- 緑 - 2 もしくは BitmapDataChannel.GREEN
- 青 - 1 もしくは BitmapDataChannel.BLUE
となります。
コピーできるのは一つのチャンネルだけなので、BitmapDataChannel.RED | BitmapDataChannel.BLUEのような論理和の指定は出来ません。
dest.copyChannel(srcbd, srcbd.rect, new Point(), BitmapDataChannel.RED, ...続く);
この場合、赤を指定しています。4と数値で指定しても構いません。
第五引数
- destChannel:uint
- コピー先のチャンネルを指定します。
- 指定方法は第四引数のsourceChannelと同じです。
dest.copyChannel(srcbd, srcbd.rect, new Point(), BitmapDataChannel.RED, BitmapDataChannel.BLUE);
sourceChannelに赤、destChannelに青を指定してるので、
コピー元BitmapDataの赤チャンネルを、コピー先BitmapDataの青チャンネルにコピーすることになります。
コピー元BitmapDataの赤チャンネルを、コピー先BitmapDataの青チャンネルにコピーすることになります。
引数の説明はこれで終わりです。
実際にコードを書いてみて覚えましょう。
実際にコードを書いてみて覚えましょう。
サンプル
private function copyChannel(bd:BitmapData, srcColor:uint, destColor:uint):BitmapData
{
var dest:BitmapData = new BitmapData(bd.width, bd.height, true, 0xFF000000);
dest.copyChannel(bd, bd.rect, new Point(), srcColor, destColor);
return dest;
}
BitmapData#copyChannel()を使いやすいようにして新たにメソッドを定義しました。
名前が被っていてややこしいですが名前はcopyChannel()にします。
名前が被っていてややこしいですが名前はcopyChannel()にします。
対象のBitmapData、コピー元のチャンネル、コピー先のチャンネルを指定すると、そのチャンネルだけが入ったBitmapDataを返却するメソッドです。
残りのチャンネルは全て0が入ります。
残りのチャンネルは全て0が入ります。
要は、
| コピー元 | A(255) | R(53) | G(144) | B(178) |
の状態で、上で書いたメソッドcopyChannel(bd, BitmapDataChannel.RED, BitmapDataChannel.BLUE)と入れると、
| コピー先 | A(255) | R(0) | G(0) | B(53) |
になるということです。
赤のチャンネルを青に移して、残りの赤と緑は0にします。
アルファ値まで0にすると透明になってしまうので、アルファの値は255で固定です。お分かりいただけたでしょうか。
赤のチャンネルを青に移して、残りの赤と緑は0にします。
アルファ値まで0にすると透明になってしまうので、アルファの値は255で固定です。お分かりいただけたでしょうか。
元画像です。
addChild(new Bitmap(copyChannel(bd, BitmapDataChannel.RED, BitmapDataChannel.RED)));
コピー元赤チャンネルをコピー先赤チャンネルにコピーしました。
(アルファ:255, 赤:コピー元の値, 緑:0, 青:0)
(アルファ:255, 赤:コピー元の値, 緑:0, 青:0)
addChild(new Bitmap(copyChannel(bd, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN)));
コピー元緑チャンネルをコピー先緑チャンネルにコピーしました。
(アルファ:255, 赤:0, 緑:コピー元の値, 青:0)
(アルファ:255, 赤:0, 緑:コピー元の値, 青:0)
addChild(new Bitmap(copyChannel(bd, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE)));
コピー元青チャンネルをコピー先青チャンネルにコピーしました。
(アルファ:255, 赤:0, 緑:0, 青:コピー元の値)
(アルファ:255, 赤:0, 緑:0, 青:コピー元の値)
検証用コード
package
{
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.events.Event;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.system.Security;
import flash.display.BitmapDataChannel;
public class Main extends Sprite
{
private const WIDTH:int = 200; // 幅
private const HEIGHT:int = 200; // 高さ
public function Main()
{
Security.loadPolicyFile("http://farm3.static.flickr.com/crossdomain.xml");
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
loader.load(new URLRequest("http://farm4.static.flickr.com/3045/2821192319_c318b7b272.jpg"), new LoaderContext(true)); // 読み込みたい画像URL
}
private function initHandler(event:Event):void
{
var loader:Loader = event.currentTarget.loader;
var matrix:Matrix = new Matrix();
matrix.scale(WIDTH / loader.width, HEIGHT / loader.height); // 設定したいサイズ / 元サイズ
var bd:BitmapData = new BitmapData(WIDTH, HEIGHT); // 設定したいサイズ
bd.draw(loader, matrix);
addChild(new Bitmap(copyChannel(bd, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE)));
}
private function copyChannel(bd:BitmapData, srcColor:uint, destColor:uint):BitmapData
{
var dest:BitmapData = new BitmapData(bd.width, bd.height, true, 0xFF000000);
dest.copyChannel(bd, bd.rect, new Point(), srcColor, destColor);
return dest;
}
}
}
このwikiの更新情報RSS