ハーフトーンカメラ(カラー)
前回のエントリに引き続きハーフトーンカメラ処理、今度はカラー版です。
RGBそれぞれに対してハーフトーン処理を行うと、8色に減色できるようなのでこちらも作ってみました。
大部分はモノクロ版と同じですが、最後の変換を paletteMap で一括変換しています。
こちらも全ピクセルをなめる必要なし。
画像処理様様ですね。
ソースは以下。
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.Camera;
import flash.media.Video;
[SWF(backgroundColor=0x000000, frameRate='30', width='320', height='240')]
public class HalftoneColor extends Sprite {
private const CAMERA_W:int = 320;
private const CAMERA_H:int = 240;
private var camera:Camera;
private var video:Video;
private var effect_bd:BitmapData;
private var pattern_bd:BitmapData;
private var rect:Rectangle;
private var zero:Point;
private var mtx:Matrix;
private var rPalette:Array;
private var gPalette:Array;
private var bPalette:Array;
private var bayer_arr:Array = [
0, 8, 2, 10,
12, 4, 14, 6,
3, 11, 1, 9,
15, 7, 13, 5
];
public function HalftoneColor() {
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.BEST;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
}
private function mouseUpHandler( e:MouseEvent ):void {
stage.removeEventListener( e.type, arguments.callee );
camera = Camera.getCamera();
if ( camera != null ) {
setupPalette();
setupPattern();
setupEffect();
}
}
private function setupPalette():void {
rPalette = new Array( 256 );
gPalette = new Array( 256 );
bPalette = new Array( 256 );
for ( var i:int = 1; i < 256; ++i ){
rPalette[ i ] = 0xff0000;
gPalette[ i ] = 0x00ff00;
bPalette[ i ] = 0x0000ff;
}
}
private function setupPattern():void {
var bayer_bd:BitmapData = new BitmapData( 4, 4, false, 0x000000 );
for ( var y:int = 0; y < 4; ++y ) {
for ( var x:int = 0; x < 4; ++x ) {
var c:int = bayer_arr[ 4*y+x ]*16+8;
bayer_bd.setPixel( x, y, c << 16 | c << 8 | c );
}
}
var temp:Shape = new Shape();
temp.graphics.beginBitmapFill( bayer_bd );
temp.graphics.drawRect( 0, 0, CAMERA_W, CAMERA_H );
temp.graphics.endFill();
pattern_bd = new BitmapData( CAMERA_W, CAMERA_H, false, 0x000000 );
pattern_bd.draw( temp );
bayer_bd.dispose();
temp.graphics.clear();
}
private function setupEffect():void {
video = new Video( CAMERA_W, CAMERA_H );
video.attachCamera( camera );
rect = new Rectangle( 0, 0, CAMERA_W, CAMERA_H );
zero = new Point();
mtx = new Matrix();
effect_bd = new BitmapData( CAMERA_W, CAMERA_H, false, 0x000000 );
addChild( new Bitmap( effect_bd ) );
update();
stage.addEventListener( Event.ENTER_FRAME, update );
}
private function update( e:Event = null ):void {
effect_bd.lock();
effect_bd.draw( video );
effect_bd.draw( pattern_bd, mtx, null, "subtract");
effect_bd.paletteMap( effect_bd, rect, zero, rPalette, gPalette, bPalette );
effect_bd.unlock();
}
}
}


