« 流れる雲 - perlinNoise | Main | 跳ね回る火の玉 - draw / applyFilter »

FLASHでペイント (1) エアブラシと消しゴム - copyPixels

copyPixelsでPhotoshopのようなエアブラシと消しゴムを再現。ビットマップの描画はdrawでも代替可能ですが、drawではビットマップをアルファに置き換えることができないので、消しゴムを再現するにはcopyPixelsを使う必要があります。

copy_pixels イメージ

サンプルではレイヤーのblendModeを変更できるようにしてますが、下のスクリプトは描画関係に絞って記述してあります。ライブラリ内に背景イメージ(下記では"himawari")とブラシのイメージ(同"air_circle35")を設置してスクリプトに書き出しておく必要があります。長いので分けて配置していますが、すべて1フレーム目に記述。

import flash.display.*;
import flash.geom.*;

var now_tool:String = "brush";

// --- ビットマップ作成

var img:BitmapData = BitmapData.loadBitmap("himawari");
var layer:BitmapData = new BitmapData(300, 220, true, 0); 
var brush_shape:BitmapData = BitmapData.loadBitmap("air_circle35");
var brush_src:BitmapData = new BitmapData(360, 240, true, 0xFF660000);

// --- ムービークリップ作成 & ビットマップ貼り付け

var bgmc:MovieClip = this.createEmptyMovieClip("bg_mc", 0);
var stage:MovieClip = this.createEmptyMovieClip("stage_mc", 1);
var brimg:MovieClip = this.createEmptyMovieClip("circle_mc", 2);

stage._x = bgmc._x = 50;
stage._y = 10;

stage.attachBitmap(layer, 1);
bgmc.attachBitmap(img, 1);
brimg.attachBitmap(brush_shape, 1);

次に、消しゴムを作成するため、

1. アルファマスク用に白の矩形ビットマップ(eraser_shape)を作成
2. ブラシのビットマップを読み込んだMC(brimg)をdrawでeraser_shapeに描画
3. copyChannelでブラシ部分を透明にして型抜き
4. copyPixelsで [アルファの結合(mergeAlpha)] パラメータをfalseに設定して対象自身(layer)をコピー

・・・の手順。(もう少しいい方法がありそうな気もしますが・・・。)

// --- 消しゴム作成

var eraser_shape:BitmapData = new BitmapData(brush_shape.width, brush_shape.height, true, 0xFFFFFFFF);
eraser_shape.draw(brimg);
eraser_shape.copyChannel(eraser_shape, eraser_shape.rectangle, new Point(0, 0), 1, 8);

brimg.removeMovieClip();

// --- ブラシを使う

function useBrush():Void {
	var offset:Point = new Point(stage._xmouse-brush_shape.width/2, stage._ymouse-brush_shape.height/2);
	var rect:Rectangle = new Rectangle(offset.x, offset.y, brush_shape.width, brush_shape.height);	
	layer.copyPixels(brush_src, rect, offset, brush_shape, new Point(0, 0), true);
	updateAfterEvent();
}

// --- 消しゴムを使う

function useEraser():Void {
	var offset:Point = new Point(stage._xmouse-eraser_shape.width/2, stage._ymouse-eraser_shape.height/2);
	var rect:Rectangle = new Rectangle(offset.x, offset.y, eraser_shape.width, eraser_shape.height);	
	layer.copyPixels(layer, rect, offset, eraser_shape, new Point(0, 0), false);
	updateAfterEvent();
}

// --- マウスイベント

this.onMouseDown = function():Void {
	if (stage.hitTest(this._xmouse, this._ymouse, true)) {
		switch (now_tool) {
			case "brush": 
			this.onMouseMove = useBrush;
			useBrush();
			break;
			
			case "eraser":
			this.onMouseMove = useEraser;
			useEraser();
			break;
		}
	}
}

this.onMouseUp = function():Void {
	delete this.onMouseMove;
}

// --- ボタン

brushBtn_mc.onPress = function ():Void {
	changeTool("brush");
}

eraserBtn_mc.onPress = function():Void {
	changeTool("eraser");
}

function changeTool(tool:String):Void {
	now_tool = tool;
}

BitmapDataの基本的な操作は以下を参照。
Flash 8 のイメージ API の概要(Macromedia - Developer Center)

TrackBack

このエントリーのトラックバックURL:
http://casualplay.net/cgi-bin/mt/mt-tb.cgi/12

Post a Comment