flex_ASCII图表示例;

效果:


=>ImageInfo.as

package com.cen.programmingas3.asciiArt
{
/**
* 位图信息类:包含位图的相关信息;
* @author cen
*/
public class ImageInfo
{
/**
* constructor
*/
public function ImageInfo()
{
}

/**
* 类属性*/
/*文件名称*/
public var fileName:String;
/*文件标题*/
public var title:String;
/*白色阀值*/
public var whiteThreshold:uint;
/*黑色阀值*/
public var blackThreshold:uint;
}
}


=>Image.as

package com.cen.programmingas3.asciiArt
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLRequest;

/**
* 位图图像类
* @author cen
*/
public class Image extends EventDispatcher
{


/**
* 私有变量*/
/*Loader 类可用于加载 SWF文件或图像(JPG、PNG 或 GIF)文件。使用 load()方法来启动加载。被加载的显示对象将作为 Loader对象的子级添加。*/
private var _loader:Loader;

/**
* 公共属性*/
/*位图*/
public var info:ImageInfo;

/**
* constructor
* @param imageInfo
*/
public function Image(imageInfo:ImageInfo)
{
this.info = imageInfo;

/*
* 文件加载类*/
_loader = new Loader();

/*_loader.contentLoaderInfo[只读] 返回与正在加载的对象相对应的LoaderInfo对象;*/
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
}

//-public method-//
/**
* 加载图像文件
*/
public function load():void{
var request:URLRequest = new URLRequest(AsciiArtBuilder.IMAGE_PATH+info.fileName);
_loader.load(request);
}

/**
* 获取位图BitmapData信息;
* @return 
*/
public function getBitmapData():BitmapData{
return Bitmap(_loader.content).bitmapData;
}

//-Event Handling-//
/**
* 图像加载完成
* @param event
*/
private function onCompleteHandler(event:Event):void{
dispatchEvent(event);
}

}
}


=>BitmapToAsciiConverter.as

package com.cen.programmingas3.asciiArt
{
import flash.display.BitmapData;

/**
* 位图转换成字符图类
* about:Provides functionality(功能) for converting a bitmap image to an "ASCII Art" representation;
* @author cen
*/
public class BitmapToAsciiConverter
{
/**
* private vars*/
/*分辨率*/
private static const _resolution:Number = .025;
/*Bitmap 对象的数据(像素)*/
private var _data:BitmapData;
/*白色阀值*/
private var _whiteThreshold:Number;
/*黑色阀值*/
private var _blackThreshold:Number;
/*调色板
=>The characters in this string become increasingly(越来越) darker(深色);
=>This set of characters are the "grayscale(灰度) values" which are used to create the image;
=>There are 64 characters, meaning each character is used to represent four values in a common
256-value grayscale color palette (which has color values in the 0-255 range);
=>The characters are in order from darkest to lightest, so that their position (index)
in the string corresponds(对应) to a relative color value (with 0 = black).
*/
private static const palette:String = "@#$%&8BMW*mwqpdbkhaoQ0OZXYUJCLtfjzxnuvcr[]{}1()|/?Il!i><+_~-;,. ";


/**
* constructor
* @param image
*/
public function BitmapToAsciiConverter(image:Image)
{
this._data = image.getBitmapData();
this._whiteThreshold = image.info.whiteThreshold;
this._blackThreshold = image.info.blackThreshold;
}


//-public method-//
/**
* 转换
* @about_Parses(解析) the bitmap data associated with(与…相联系) this instance and converts it to its "ASCII Art"
* (String) representation;
* @return string_The String representation of the bitmap image;
*/
public function parseBitmapData():String{
/*(red,green,blue)红绿蓝颜色表示法*/
var rgbVal:uint;
var redVal:uint;
var greenVal:uint;
var blueVal:uint;
/*灰色*/
var grayVal:uint;
var index:uint;

var verticalResolution:uint = Math.floor(_data.height * _resolution);
var horizontalResolution:uint = Math.floor(_data.width * _resolution * 0.45);

/*返回结果字符串*/
var result:String = "";

/**
* Loop through the rows of pixels top to bottom*/
for(var y:uint = 0; y<_data.height; y+=verticalResolution) {
/**
* loop through the left to right*/
for(var x:uint = 0; x<_data.width; x+=horizontalResolution) {
/**
* Extract(提取) individual(单个的) red, green, and blue values for the pixel*/
rgbVal = _data.getPixel(x,y);
redVal = (rgbVal & 0xFF0000) >> 16;
greenVal = (rgbVal & 0x00FF00) >> 8;
blueVal = rgbVal & 0x0000FF;

/**
* 灰度计算公式
* Calculate(计算) the gray value of the pixel:
* The formula(公式) for grayscale(灰度) conversion(转换): (Y = gray): Y = 0.3*R + 0.59*G + 0.11*B*/
grayVal = Math.floor(0.3*redVal + 0.59*greenVal + 0.11*blueVal);


/**
* 根据阀值确定灰度值:
* The white threshold and black threshold values (read from the "images.txt" file)
* determine the grayscale values that are the cut-off(界限) limits for white and black.
* Values outside the threshold will be "rounded" to pure(纯) white or black.*/
if(grayVal > _whiteThreshold) {
grayVal = 0xFF;
}else if(grayVal < _blackThreshold) {
grayVal = 0x00;
}else {
/**
* 灰度值居中时:
* Normalize(使标准化) the grayscale value along the relative scale between the white threshold
* and the black threshold. In other words(换句话说), adjust(调整) the palette so that
* the black threshold acts as the "0x00" value and the white threshold acts as the "0xFF(白)" value,*/
grayVal = Math.floor(0xFF * ((grayVal - _blackThreshold)/(_whiteThreshold - _blackThreshold)));
}

/**
* 获取此像素下标值:
* The value is now a gray value in the 0-255 range, which needs to be converted
* to a value in the 0-64 range (since that's the number of available "shades of gray*/
index = Math.floor(grayVal/4);
result += palette.charAt(index);
}
/*在行末添加换行符*/
result += "\n";
}
return result;
}
}
}


=>AsciiArtBuilder.as

package com.cen.programmingas3.asciiArt
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLLoader;
import flash.net.URLRequest;

import com.cen.programmingas3.asciiArt.ImageInfo;
import com.cen.programmingas3.asciiArt.Image;
import com.cen.programmingas3.asciiArt.BitmapToAsciiConverter;

/**
* 字符图(AsciiArt)创建类
* about:Provides application-level functionality for the AsciiArt sample;
* @author cen
*/
public class AsciiArtBuilder extends EventDispatcher
{
/**
* private vars*/
/*位图信息文本文件路径*/
private const DATA_TARGET:String = "public/txt/ImageData.txt";
/*位图信息文件加载器*/
private var _imageInfoLoader:URLLoader;
/*位图集数组*/
private var _imageStack:Array;
/*当前位图下标值*/
private var _currentImageIndex:uint;

/**
* public properties*/
/*存储位图文件夹路径*/
public static const IMAGE_PATH:String = "public/img/";

/*当前位图字符图字符串(初始化时为第一副位图)*/
public var asciiArtText:String = "";

/*获取当前位图*/
public function get currentImage():Image{
return _imageStack[_currentImageIndex];
}

/**
* constructor
*/
public function AsciiArtBuilder()
{
_imageStack = new Array;

/**
* 加载位图信息文本文件*/
var request:URLRequest = new URLRequest(DATA_TARGET);
_imageInfoLoader = new URLLoader();
_imageInfoLoader.addEventListener(Event.COMPLETE, onImageInfoCompleteHandler);
_imageInfoLoader.load(request);
}



//-Event Handlers-//
/**
* 位图信息文本文件加载完成后触发
* @param event
*/
private function onImageInfoCompleteHandler(event:Event):void{
/*将位图信息文本字符串转换成位图信息数组*/
var allImageInfo:Array = parseImageInfo();

/*创建位图*/
buildImageStack(allImageInfo);
}

private function onImageCompleteHandler(event:Event):void{

/*移动到第一副位图*/
next();

/**
* 分发“初始化加载位图”完成
* notify(通知) any listeners that the application has finished its initial loading*/
var readyEvent:Event = new Event("ready");
dispatchEvent(readyEvent);
}

//-method-//
/**
* 字符串首字母大写处理
* @param word
* @return 
*/
private function capitalizeFirstLetter(word:String):String{
switch(word) {
case "and":
case "the":
case "in":
case "an":
case "or":
case "at":
case "of":
case "a":
// don't do anything to these words;
break;
default: 
var firstLetter:String = word.substr(0,1);
firstLetter = firstLetter.toUpperCase();
var otherLetters:String = word.substring(1);
word = firstLetter + otherLetters;
}
return word;
}

/**
* 处理标题信息
* @param title
* @return 
*/
private function normalizeTitle(title:String):String{
var words:Array = title.split(" ");
var len:uint = words.length;

for(var i:uint=0; i<len; i++) {
words[i] = capitalizeFirstLetter(words[i]);
}

return words.join(" ");
}

/**
* 解析位图信息文件_将位图信息文本字符串转换成位图信息数组;
* Each line of text contains info about one image, separated by tab (\t) characters;
* in this order:
* - file name
* - title
* - white threshold
* - black threshold
* Note that we skip the first line, since it only contains column headers.
* @return An Array of ImageInfo instances.
*/
private function parseImageInfo():Array{
var result:Array = new Array();

/*位图信息文件内容字符串*/
var lines:Array = _imageInfoLoader.data.split("\n");
var numLines:uint = lines.length;

/**
* 忽略第一行内容:因为那是标题行*/
for(var i:uint=1; i<numLines; i++) {
var imageInfoRaw:String = lines[i];

/**
* 去除首尾的空白
* trim(修剪) leading(开头) or trailing(结尾) white space from the current line*/
imageInfoRaw = imageInfoRaw.replace(/^ *(.*) *$/, "$1");
if(imageInfoRaw.length>0) {// 去除空行;
/*位图信息类_create a new image info record and add it to the array of image info*/
var imageInfo:ImageInfo = new ImageInfo();

/**
* 处理每行以及提值、赋值
* split the current line into values (separated by tab (\t) characters)
* and extract the individual properties*/
var imageProperties:Array = imageInfoRaw.split("\t");
imageInfo.fileName = imageProperties[0];
imageInfo.title = normalizeTitle(imageProperties[1]);// 首字母大写处理;
imageInfo.whiteThreshold = parseInt(imageProperties[2], 16);
imageInfo.blackThreshold = parseInt(imageProperties[3], 16);

result.push(imageInfo);//保存位图信息;
}
}
return result;
}

/**
* 创建位图数组
* @param imageInfo
*/
private function buildImageStack(imageInfo:Array):void{
/*位图*/
var image:Image;
/*位图信息*/
var oneImageInfo:ImageInfo;

/*监听器是否已经添加(初始化时只添加第一副位图监听器)*/
var listenerAdded:Boolean = false;

var numImages:uint = imageInfo.length;
for(var i:uint = 0; i<numImages; i++) {
_currentImageIndex = 0;
oneImageInfo = imageInfo[i];
image = new Image(oneImageInfo);
_imageStack.push(image);

if(!listenerAdded) {
image.addEventListener(Event.COMPLETE, onImageCompleteHandler);
listenerAdded = true;
}
image.load();
}
}

/**
* (完成)Advances the image stack to the next image, and populates the asciiArtText property
* with that image's ASCII Art representation.
*/
public function next():void{
_currentImageIndex++;
if(_currentImageIndex == _imageStack.length) {
_currentImageIndex = 0;
}

/**
* 获取位图字符图字符串*/
var imageConverter:BitmapToAsciiConverter = new BitmapToAsciiConverter(this.currentImage);
this.asciiArtText = imageConverter.parseBitmapData();
}

}
}


=>AsciiArtApp.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
  xmlns:s="library://ns.adobe.com/flex/spark" 
  xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
  pageTitle="TheStudioOfCenyebao_AsciiArtDemo"
  creationComplete="creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import com.cen.programmingas3.asciiArt.AsciiArtBuilder;
import com.cen.programmingas3.asciiArt.ImageInfo;

import mx.events.FlexEvent;

/*位图字符图创建变量*/
private var asciiArt:AsciiArtBuilder;

/**
* 页面创建完成
*/
protected function creationCompleteHandler(event:FlexEvent):void
{
asciiArt = new AsciiArtBuilder();

/**
* 监听初始化是否完成*/
asciiArt.addEventListener("ready", imageReady);
}

/**
* Called when the AsciiArtBuilder has loaded the image data and is ready to display an image.
*/
private function imageReady(event:Event):void{
updatePreview();
}

/**
* Updates the image preview display, including title and image, using the current image in the asciiArt object.
*/
private function updatePreview():void{
/*位图信息*/
var imageInfo:ImageInfo = asciiArt.currentImage.info;

/*位图显示*/
img.load(AsciiArtBuilder.IMAGE_PATH + imageInfo.fileName);

/*标题信息*/
sourceImage.title = imageInfo.title;

/*显示字符图*/
asciiArtText.text = asciiArt.asciiArtText;
}

/**
* 按钮单击事件
*/
private function onNextBtnClickHandler(event:MouseEvent):void{
/*跳到下一幅位图*/
asciiArt.next();

/*update the image preview*/
updatePreview();
}
]]>
</fx:Script>

<!--位图转换字符图示例-->
<s:HGroup verticalAlign="bottom"
 horizontalCenter="0" verticalCenter="0">
<s:Panel id="sourceImage" height="100%"
backgroundColor="#b7babc" borderAlpha="1" borderColor="#666">
<s:VGroup width="100%" height="100%" verticalAlign="middle" horizontalAlign="center">
<mx:Image id="img" width="400" height="300"/>
</s:VGroup>
<s:controlBarContent>
<s:Spacer width="90%"/>
<s:Button id="nextBtn" buttonMode="true" useHandCursor="true"
 label="NextImage" click="onNextBtnClickHandler(event)"/>
</s:controlBarContent>
</s:Panel>
<s:TextArea id="asciiArtText" fontSize="8" fontFamily="_typewriter"
width="550" height="450"/>
</s:HGroup>

</s:Application>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值