Ascii Webcam
Generating ASCII art from webcam data
Generating ASCII art from webcam data
/*
_____ __________________ .___.___
/ _ \ / _____/\_ ___ \| | |
/ /_\ \ \_____ \ / \ \/| | |
/ | \/ \ \___| | |
\____|__ /_______ / \______ /___|___|
\/ ___. \/ \/
__ _ __ ____\_ |__ ____ _____ _____
\ \/ \/ // __ \| __ \_/ ___\__ \ / \
\ /\ ___/| \_\ \ \___ / __ \| Y Y \
\/\_/ \___ >___ /\___ >____ /__|_| /
\/ \/ \/ \/ \/
*/
package {
//______________________________________________________________________________
// imports
import com.bit101.components.*;
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.media.*;
import flash.text.*;
import flash.ui.*;
import flash.utils.*;
import nu.xero.gfx.*;
//______________________________________________________________________________
// export
[SWF(backgroundColor="0xffffff",
heightPercent="100%",
widthPercent="100%",
pageTitle="ascii webcam")]
//______________________________________________________________________________
// class
public class main extends Sprite {
//______________________________________________________________________________
// vars
private var webcam :Video;
private var camera :Camera;
private var webcamData :Bitmap
private var tempData :BitmapData;
private var converter :bitmap2ascii;
private var format :TextFormat;
private var canvas :TextField;
private var form :Sprite;
private var fontSlider :Slider;
private var resSlider :Slider;
private var blackSlider :Slider;
private var whiteSlider :Slider;
private var fontColor :ColorChooser;
private var bgColor :ColorChooser;
private var chkPreview :CheckBox;
private var preview :Sprite;
private var shrink :Matrix;
//______________________________________________________________________________
// constructor
public function main() {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.MEDIUM;
stage.frameRate = 100;
createUI();
createMenu();
initCams();
}
//______________________________________________________________________________
// setup interface
private function createUI():void {
format = new TextFormat("Courier New", 6);
Style.setStyle('dark');
canvas = new TextField();
canvas.autoSize = TextFieldAutoSize.LEFT;
canvas.x = 80;
canvas.y = 0
canvas.wordWrap = false;
canvas.selectable = false;
canvas.defaultTextFormat = format;
addChild(canvas);
form = new Sprite();
form.x = form.y = 0;
form.graphics.beginFill(0x222222);
form.graphics.drawRect(0, 0, 80, stage.stageHeight);
addChild(form);
var lblFont:Label = new Label();
lblFont.x = 0;
lblFont.y = 20;
lblFont.text = "font size";
form.addChild(lblFont);
fontSlider = new Slider(Slider.HORIZONTAL);
fontSlider.scaleX = fontSlider.scaleY = 0.75;
fontSlider.x = 2;
fontSlider.y = 40;
fontSlider.minimum = 4;
fontSlider.maximum = 10;
fontSlider.value = 6;
fontSlider.addEventListener(Event.CHANGE, fontChange);
form.addChild(fontSlider);
var lblRes:Label = new Label();
lblRes.x = 0;
lblRes.y = 50;
lblRes.text = "resolution";
form.addChild(lblRes);
resSlider = new Slider(Slider.HORIZONTAL);
resSlider.scaleX = resSlider.scaleY = 0.75;
resSlider.x = 2;
resSlider.y = 70;
resSlider.minimum = 0.01;
resSlider.maximum = 0.05;
resSlider.value = 0.025;
resSlider.addEventListener(Event.CHANGE, formChange);
form.addChild(resSlider);
var lblBlack:Label = new Label();
lblBlack.x = 0;
lblBlack.y = 80;
lblBlack.text = "black threshold";
form.addChild(lblBlack);
blackSlider = new Slider(Slider.HORIZONTAL);
blackSlider.scaleX = blackSlider.scaleY = 0.75;
blackSlider.x = 2;
blackSlider.y = 100;
blackSlider.minimum = 0;
blackSlider.maximum = 40;
blackSlider.value = 40;
blackSlider.addEventListener(Event.CHANGE, formChange);
form.addChild(blackSlider);
var lblWhite:Label = new Label();
lblWhite.x = 0;
lblWhite.y = 110;
lblWhite.text = "white threshold";
form.addChild(lblWhite);
whiteSlider = new Slider(Slider.HORIZONTAL);
whiteSlider.scaleX = whiteSlider.scaleY = 0.75;
whiteSlider.x = 2;
whiteSlider.y = 130;
whiteSlider.minimum = 10;
whiteSlider.maximum = 255;
whiteSlider.value = 200;
whiteSlider.addEventListener(Event.CHANGE, formChange);
form.addChild(whiteSlider);
var lblBgColor:Label = new Label();
lblBgColor.x = 0;
lblBgColor.y = 140;
lblBgColor.text = "background color";
form.addChild(lblBgColor);
bgColor = new ColorChooser();
bgColor.value = 0xffffff;
bgColor.x = 5;
bgColor.y = 160;
bgColor.usePopup = true;
bgColor.addEventListener(Event.CHANGE, colorChange);
form.addChild(bgColor);
var lblFontColor:Label = new Label();
lblFontColor.x = 0;
lblFontColor.y = 180;
lblFontColor.text = "font color";
form.addChild(lblFontColor);
fontColor = new ColorChooser();
fontColor.value = 0x000000;
fontColor.x = 5;
fontColor.y = 200;
fontColor.usePopup = true;
fontColor.addEventListener(Event.CHANGE, fontChange);
form.addChild(fontColor);
var lblPreview:Label = new Label();
lblPreview.x = 0;
lblPreview.y = 220;
lblPreview.text = "preview";
form.addChild(lblPreview);
chkPreview = new CheckBox();
chkPreview.x = 45;
chkPreview.y = 225;
chkPreview.selected = true;
chkPreview.addEventListener(Event.CHANGE, formChange);
form.addChild(chkPreview);
shrink = new Matrix();
shrink.scale(0.25, 0.25);
preview = new Sprite();
preview.x = 0;
preview.y = 240;
addChild(preview);
}
private function colorChange(e:Event):void {
graphics.beginFill(bgColor.value);
graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
graphics.endFill();
}
private function fontChange(e:Event):void {
format = new TextFormat("Courier New", fontSlider.value, fontColor.value);
canvas.defaultTextFormat = format;
}
private function formChange(e:Event):void {
converter.resolution = resSlider.value;
converter.blackThreshold = blackSlider.value;
converter.whiteThreshold = whiteSlider.value;
}
//______________________________________________________________________________
// menu
private function createMenu():void {
var menu:ContextMenu = new ContextMenu();
menu.addEventListener(ContextMenuEvent.MENU_SELECT, menuHandler);
menu.hideBuiltInItems();
var menuFullscreen:ContextMenuItem = new ContextMenuItem("go fullscreen");
menuFullscreen.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, goFullscreen);
menu.customItems.push(menuFullscreen);
var menuExitFull:ContextMenuItem = new ContextMenuItem("exit fullscreen");
menuExitFull.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, exitFullscreen);
menu.customItems.push(menuExitFull);
this.contextMenu = menu;
}
private function menuHandler(e:ContextMenuEvent):void {
if (stage.displayState == StageDisplayState.NORMAL) {
e.target.customItems[0].enabled = true;
e.target.customItems[1].enabled = false;
} else {
e.target.customItems[0].enabled = false;
e.target.customItems[1].enabled = true;
}
}
private function goFullscreen(e:ContextMenuEvent):void {
stage.displayState = StageDisplayState.FULL_SCREEN;
}
private function exitFullscreen(e:ContextMenuEvent):void {
stage.displayState = StageDisplayState.NORMAL;
}
//______________________________________________________________________________
// webcam
private function initCams():void {
camera = Camera.getCamera();
camera.addEventListener(StatusEvent.STATUS, onCamStatus);
webcam = new Video(320, 240);
webcam.attachCamera(camera);
tempData = new BitmapData(320, 240, false, 0xff0000);
webcamData = new Bitmap(tempData);
webcamData.x = 320;
converter = new bitmap2ascii(0.025, 200, 40);
converter.resolution = 0.01;
}
private function onCamStatus(e:StatusEvent):void {
if (e.code.indexOf("unmuted")) {
var chronos:Timer;
chronos = new Timer(30);
chronos.addEventListener(TimerEvent.TIMER, update);
chronos.start();
}
}
private function update(e:TimerEvent):void {
tempData.draw(webcam);
webcamData.bitmapData = tempData;
canvas.text = converter.convert(tempData);
preview.graphics.clear();
if(chkPreview.selected) {
preview.graphics.beginBitmapFill(webcamData.bitmapData, shrink);
preview.graphics.drawRect(0, 0, 80, 60);
preview.graphics.endFill();
}
return;
}
}
}
//______________________________________________________________________________
// end of file