トップページ > 画像処理 > カラーチャンネルをコピーする



概要

カラーチャンネルをコピーしてみましょう。



ARGBのA, R, G, B、一つ一つのことをチャンネルといいます。
BitmapData#copyChannel()を使用するとチャンネルごとに分けて転送することが可能です。

例えば、
  • 元BitmapDataの青色を、コピー先BitmapDataの青色にコピー
  • 元BitmapDataの赤色を、コピー先BitmapDataの緑色にコピー
という風な事が出来ます。


プログラム

対象画像の読み込み方法は、画像処理用のテンプレートを参照してください。


まずは、BitmapData#copyChannel()の使い方を説明します。

書き方としては、コピー先BitmapData.copyChannel(コピー元BitmapData)になります。

第一引数
  • sourceBitmapData:BitmapData
    • チャンネルを取得する対象のBitmapDataを指定します。

dest.copyChannel(srcbd, ...続く
 
チャンネルのコピー元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の青チャンネルにコピーすることになります。


引数の説明はこれで終わりです。
実際にコードを書いてみて覚えましょう。


サンプル

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()にします。

対象のBitmapData、コピー元のチャンネル、コピー先のチャンネルを指定すると、そのチャンネルだけが入ったBitmapDataを返却するメソッドです。
残りのチャンネルは全て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で固定です。お分かりいただけたでしょうか。


元画像です。


addChild(new Bitmap(copyChannel(bd, BitmapDataChannel.RED, BitmapDataChannel.RED)));
 
コピー元赤チャンネルをコピー先赤チャンネルにコピーしました。
(アルファ:255, 赤:コピー元の値, 緑:0, 青:0)


addChild(new Bitmap(copyChannel(bd, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN)));
 
コピー元緑チャンネルをコピー先緑チャンネルにコピーしました。
(アルファ:255, 赤:0, 緑:コピー元の値, 青:0)


addChild(new Bitmap(copyChannel(bd, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE)));
 
コピー元青チャンネルをコピー先青チャンネルにコピーしました。
(アルファ: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;
		}
	}
}
 

|新しいページ|検索|ページ一覧|RSS|@ウィキご利用ガイド | 管理者にお問合せ
|ログイン|