forked from: Dither
1st step : press "Pattern Randomize" or "Bayer set".
2ed step : press "Apply".
or
1st step : rewrite number of TextField.(Positive integer from 0 to 15)
2ed step : press "Apply".
/**
* Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/47Kg
*/
// forked from Aquioux's Dither
package {
import flash.geom.Matrix;
//import aquioux.display.bitmapDataEffector.GrayScale;
//import aquioux.utils.ButtonMediator;
import com.bit101.components.PushButton;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.system.LoaderContext;
/**
* ハーフトーニング(ランダムディザと組織的ディザ)
* @see http://aquioux.net/blog/?p=2700
* @author YOSHIDA, Akio (Aquioux)
*/
[SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "#FFFFFF")]
public class Main extends Sprite {
// ビューア BitmapData
private var viewBmd_:BitmapData;
// BitmapData#getVector で得られる値
private var sourcePixelList_:Vector.<uint>; // ソース画像
private var grayPixelList_:Vector.<uint>; // グレイスケール画像
// BitmapData#setVector 用
private var rect_:Rectangle;
// ディザクラス
private var orderedDither_:OrderedDither; // 組織的ディザ法
// パターン管理クラス
private var patternManager_:PatternManager;
// コンストラクタ
public function Main() {
var url:String = "http://assets.wonderfl.net/images/related_images/3/39/39f6/39f64cad1c50914c2c459386feeddf6d915cea06m";
var loader:Loader = new Loader();
loader.load(new URLRequest(url), new LoaderContext(true));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
}
private function completeHandler(event:Event):void {
// ソースイメージ
var loadedBmd:BitmapData = event.target.loader.content.bitmapData;
var sourceBmd:BitmapData = new BitmapData(180, 215);
sourceBmd.draw(loadedBmd, new Matrix(180/200, 0, 0, 215/200));
rect_ = sourceBmd.rect;
sourcePixelList_ = sourceBmd.getVector(rect_);
// グレイスケール BitmapData
var grayBmd:BitmapData = sourceBmd.clone();
new GrayScale().applyEffect(grayBmd);
grayPixelList_ = grayBmd.getVector(rect_);
grayBmd.dispose();
// ビューア
viewBmd_ = sourceBmd;
var viewBm:Bitmap = new Bitmap(viewBmd_);
viewBm.x = (stage.stageWidth - viewBm.width ) / 2 >> 0;
viewBm.y = (stage.stageHeight - viewBm.height ) / 2 >> 0;
addChild(viewBm);
// ディザクラス
orderedDither_ = new OrderedDither();
// パターン・マトリックス
patternManager_ = new PatternManager();
addChild(patternManager_);
// ボタン
var buttonWidth:int = 100;
var buttonHeight:int = 20;
var button0:PushButton = new PushButton(this, 0, 80 + buttonHeight * 0, "Pattern Randomize", randomHander);
var button1:PushButton = new PushButton(this, 0, 80 + buttonHeight * 1, "Bayer set", bayerHander);
var button2:PushButton = new PushButton(this, 0, 80 + buttonHeight * 2, "Apply", applyHander);
var button3:PushButton = new PushButton(this, 0, 80 + buttonHeight * 4, "Original", originalHander);
button0.width = buttonWidth;
button1.width = buttonWidth;
button2.width = buttonWidth;
button3.width = buttonWidth;
}
// オリジナル画像
private function originalHander(event:Event):void {
viewBmd_.setVector(rect_, sourcePixelList_);
}
// PatternManager の値をランダムにする
private function randomHander(event:Event):void {
patternManager_.random();
}
// Bayer 型
private function bayerHander(event:Event):void {
// パターン適用
var pattern:Vector.<uint> = Vector.<uint>([
0, 8, 2, 10,
12, 4, 14, 6,
3, 11, 1, 9,
15, 7, 13, 5
]);
patternManager_.value = pattern;
}
// ディザ実行
private function applyHander(event:Event):void {
viewBmd_.setVector(rect_, grayPixelList_);
orderedDither_.matrix = patternManager_.value;
orderedDither_.execute(viewBmd_);
}
}
}
//package {
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.geom.Rectangle;
/**
* 組織的ディザ
* @author YOSHIDA, Akio (Aquioux)
*/
/*public*/ class OrderedDither extends EventDispatcher {
/**
* ディザ・マトリクス
*/
public function set matrix(value:Vector.<uint>):void {
_matrix = value;
var len:int = _matrix.length;
for (var i:int = 0; i < len; i++) _matrix[i] = _matrix[i] * 16 + 8;
}
private var _matrix:Vector.<uint> = Vector.<uint>([
0, 8, 2, 10,
12, 4, 14, 6,
3, 11, 1, 9,
15, 7, 13, 5
]); // Bayer 型
/**
* コンストラクタ
*/
public function OrderedDither() {
matrix = _matrix;
}
/**
* ディザ実行
*/
public function execute(bmd:BitmapData):void {
var imageWidth:int = bmd.width;
var rect:Rectangle = bmd.rect;
var pixelList:Vector.<uint> = bmd.getVector(rect);
// 走査
var len:uint = pixelList.length;
for (var i:int = 0; i < len; i++) {
var idxX:int = (i % imageWidth) % 4;
var idxY:int = (i / imageWidth >> 0) % 4;
var threshold:int = _matrix[idxY * 4 + idxX];
var gray:uint = pixelList[i] & 0xFF;
pixelList[i] = gray >= threshold ? 0xFFFFFFFF : 0xFF000000;
}
bmd.setVector(rect, pixelList);
dispatchEvent(new Event(Event.COMPLETE));
}
}
//}
//package {
import com.bit101.components.Text;
import flash.display.Sprite;
/**
* パターン管理クラス
* @author YOSHIDA, Akio (Aquioux)
*/
/*public*/ class PatternManager extends Sprite {
/**
* パターンの値
*/
public function set value(value:Vector.<uint>):void {
for (var i:int = 0; i < 16; i++) textList_[i].text = String(value[i]);
}
public function get value():Vector.<uint> {
var retrunValue:Vector.<uint> = new Vector.<uint>(16, true);
for (var i:int = 0; i < 16; i++) retrunValue[i] = uint(textList_[i].text);
return retrunValue;
}
private var _value:Vector.<uint>;
// テキストフィールド(minimalComps の Text)のリスト
private var textList_:Vector.<Text>
// パターン・マトリックスの値のリスト
private var matrixValueList_:Vector.<uint>;
/**
* コンストラクタ
*/
public function PatternManager() {
matrixValueList_ = new Vector.<uint>(16, true);
textList_ = new Vector.<Text>(16, true);
var w:int = 25;
var h:int = 20;
var initValue:uint = 0
for (var i:int = 0; i < 16; i++) {
var text:Text = new Text(this, (i % 4) * w, (i / 4 >> 0) * h, String(initValue));
text.width = w;
text.height = h;
text.name = String(i);
matrixValueList_[i] = initValue;
textList_[i] = text;
}
}
public function random():void {
// リストの再生成
for (var i:int = 0; i < 16; i++) matrixValueList_[i] = i;
// リストのシャッフル
var num:int;
var tmp:uint;
var len:int = 16;
while (len--) {
num = Math.floor(Math.random() * (len + 1));
tmp = matrixValueList_[len];
matrixValueList_[len] = matrixValueList_[num];
matrixValueList_[num] = tmp;
}
// リストの内容を Text.text に転送
for (i = 0; i < 16; i++) textList_[i].text = String(matrixValueList_[i]);
}
}
//}
//package aquioux.display.bitmapDataEffector {
import flash.display.BitmapData;
import flash.filters.ColorMatrixFilter;
import flash.geom.Point;
/**
* ColorMatrixFilter による BitmapData のグレイスケール化(NTSC 系加重平均による)
* 参考:Foundation ActionScript 3.0 Image Effects(P106)
* http://www.amazon.co.jp/gp/product/1430218711?ie=UTF8&tag=laxcomplex-22
* @author YOSHIDA, Akio (Aquioux)
*/
/*public*/ class GrayScale implements IEffector {
private const R:Number = EffectorUtils.LUM_R;
private const G:Number = EffectorUtils.LUM_G;
private const B:Number = EffectorUtils.LUM_B;
private const MATRIX:Array = [
R, G, B, 0, 0,
R, G, B, 0, 0,
R, G, B, 0, 0,
0, 0, 0, 1, 0
];
private const FILTER:ColorMatrixFilter = new ColorMatrixFilter(MATRIX);
private const ZERO_POINT:Point = EffectorUtils.ZERO_POINT;
/*
* 効果適用
* @param value 効果対象 BitmapData
*/
public function applyEffect(value:BitmapData):BitmapData {
value.applyFilter(value, value.rect, ZERO_POINT, FILTER);
return value;
}
}
//}
//package aquioux.display.bitmapDataEffector {
import flash.display.BitmapData;
/**
* BitmapDataEffector 用 interface
* @author YOSHIDA, Akio (Aquioux)
*/
/*public*/ interface IEffector {
function applyEffect(value:BitmapData):BitmapData;
}
//}
//package aquioux.display.bitmapDataEffector {
import flash.geom.Point;
/**
* bitmapDataEffector パッケージ内のクラスで共通に使う定数など
* @author YOSHIDA, Akio (Aquioux)
*/
/*public*/ class EffectorUtils {
// BitmapData が備える各種メソッドの destPoint 用
static public const ZERO_POINT:Point = new Point(0, 0);
// グレイスケール用の各チャンネルの重みづけ
// NTSC系加重平均法(YIQ,YCbCr も同じ)
static public const LUM_R:Number = 0.298912;
static public const LUM_G:Number = 0.586611;
static public const LUM_B:Number = 0.114478;
//static public const LUM_R:Number = 1/3;
//static public const LUM_G:Number = 1/3;
//static public const LUM_B:Number = 1/3;
// HDTV
//static public const LUM_R:Number = 0.2126;
//static public const LUM_G:Number = 0.7152;
//static public const LUM_B:Number = 0.0722;
}
//}