Imageprocessing Library:一个图象滤镜库

Imageprocessing Library是一个基于as3的简单高效的图像滤镜库。里面包含了五十多种对图片的处理方法。(官方介绍,没有验证)

我是在deface的官方示例中发现这个包的,简单看了一下,发现功能强大,但不是开源的。

官方博客地址:http://blog.joa-ebert.com/imageprocessing-library/

最新版本的swc地址:http://je2050.de/files/source/as3/ImageProcessing.zip

文档地址:http://je2050.de/imageprocessing/

几个示例:

仿PS的曲线工具:http://je2050.de/showroom.php?file=curves

结合pv3d做的一个示例:http://je2050.de/showroom.php?file=roto&f=1

还有一个扩展示例,说不出来的酷:http://www.sephiroth.it/test/flex/2/mixer_papervision/Main.html

ZamfBrowser:不错的ZendAMF调试工具

事实证明,经常看看那些开源项目的网站,总是会好处的.我今天逛puremvc的网站就有了一个惊喜,发现了一个基于puremvc的开源东东叫:ZamfBrowser.用这个工具,可以方便的对ZendAMF的php端程序进行测试和调试.

官方网站:http://www.zamfbrowser.org/

项目的SVN地址:http://svn.riaforge.org/zamfbrowser/

从SVN当下来的代码有两个部分,air和php.

air部分的代码,需要在flex中建一个air项目,把puremvc的代码链进来,就可以进行编译了.可以release一个版本出来,自个安装一下.注意:要air运行环境哦.

php部分的代码里面有个示例代码的zip包,实际上用到的只是sourse目录中的ZendAmfServiceBrowser.php文件.

具体使用方法如下:

1)rowser拷到你的项目中.

2)修改你的gateway.php文件.添加如下代码

require_once( "browser/ZendAmfServiceBrowser.php" );
$server->setClass( "ZendAmfServiceBrowser" );
ZendAmfServiceBrowser::$ZEND_AMF_SERVER = $server;

下面就是启动你刚刚装好的的air程序,添加一个服务,第一个框中随便填个名称,第二个框中填gateway.php的地址,就OK了.
下面你就可以对你项目中各个类中的各个方法进行测试了,设定传入的参数,查看传回的结果.
爽吧?
具体的使用帮助,请看官网的:
http://www.zamfbrowser.org/documentation.html

一个声音光谱效果的源码

偶然发现了这个效果,只有一个类,效果狂好.奉上源码

点击下面的[flash]开始欣赏.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.media.Microphone;
	import flash.media.Sound;
	import flash.media.SoundMixer;
	import flash.utils.ByteArray;
 
	[SWF( backgroundColor='0', frameRate='35', height='400', width='400')]
 
	public class Main extends Sprite
	{
 
		private var mic: Microphone;
		private var sound: Sound;
		private var bytes: ByteArray;
 
		private var output: BitmapData;
		private var peaks: BitmapData;
		private var displace: Matrix;
		private var rect: Rectangle;
		private var gradient: Array;
		private var darken: ColorTransform;
 
        [Embed(source="song.mp3")]
        public var soundClass:Class;
 
		public function Main()
		{
			sound = new soundClass as Sound;
			stage.addEventListener(MouseEvent.CLICK,onStageClicked);
 
			bytes = new ByteArray();
 
			output = new BitmapData( stage.stageWidth, stage.stageHeight, true, 0 );
			peaks = new BitmapData( stage.stageWidth, stage.stageHeight, true, 0 );
 
			displace = new Matrix();
			displace.tx = 2;
			displace.ty = -1;
 
			darken = new ColorTransform( 1, 1, 1, 1, -2, -2, -2, 0 );
 
			rect = new Rectangle( 0, 0, 1, 0 );
 
			addChild( new Bitmap( output ) );
			addChild( new Bitmap( peaks ) );
 
			stage.addEventListener( Event.ENTER_FRAME, onEnterFrame );
 
			graphics.beginFill( 0 );
			graphics.drawRect( 0, 0, stage.stageWidth, stage.stageHeight );
			graphics.endFill();
 
			gradient = createRainbowGradientArray();
		}
 
		private function onStageClicked( event:MouseEvent ): void
		{
			sound.play();
			stage.removeEventListener(MouseEvent.CLICK,onStageClicked);
		}
 
		private function onEnterFrame( event: Event ): void
		{
			peaks.fillRect( peaks.rect, 0 );
 
			SoundMixer.computeSpectrum( bytes, true, 0 );
 
			var value: Number;
			var height: Number;
 
			var smooth: Number;
 
			for( var i: int = 0 ; i < 256 ; i++ )
			{
				value = bytes.readFloat();
 
				if( i == 0 ) smooth = value;
				else smooth += ( value - smooth ) / 8;
 
				height = 2 + smooth * 0xf0;
 
				rect.x = 8 + i;
				rect.y = 320 + ( i >> 2 ) - height;
				rect.height = height;
 
				peaks.setPixel32( rect.x, rect.y, 0xffffffff );
 
				output.fillRect( rect, 0xff000000 | gradient[i] );
			}
 
			output.draw( output, displace, darken, null, null, true );
		}
 
		private function createRainbowGradientArray(): Array
		{
			var gradient: Array = new Array();
 
			var shape: Shape = new Shape();
			var bmp: BitmapData = new BitmapData( 256, 1, false, 0 );
 
			var colors: Array = [ 0, 0xff0000, 0xffff00, 0x00ff00, 0x00ffff ];
			var alphas: Array = [ 100, 100, 100, 100, 100 ];
			var ratios: Array = [ 0, 16, 128, 192, 255 ];
 
			var matrix: Matrix = new Matrix();
 
			matrix.createGradientBox( 256, 1, 0, 0, 0 );
 
			shape.graphics.beginGradientFill( 'linear', colors, alphas, ratios, matrix );
			shape.graphics.drawRect( 0, 0, 256, 1 );
			shape.graphics.endFill();
 
			bmp.draw( shape );
 
			for( var i: int = 0 ; i < 256 ; i++ )
			{
				gradient[i] = bmp.getPixel( i, 0 );
			}
 
			return gradient;
		}
	}
}

一个一百多行代码的开关灯游戏

试着关闭所有的灯:

今天在flashandmath.com上闲逛,发现了这个小游戏,前前后后只有一百多行代码.蛮有意思.

用flash cs3创建一个fla文件,然后在场景上放个按钮,起名:btnNewGame

然后贴入下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
function setupGame():void {
	tbDoneText.text = "";
	addGameBoard();
	drawBoxes();
}
 
function newGame(evt:MouseEvent):void {
	removeGameBoard();
	setupGame();
}
 
// add a listener for the "New Game" button
btnNewGame.addEventListener(MouseEvent.CLICK,newGame);
 
var boxHeight:int = 40;
var boxWidth:int = 40;
var boxXSpace:int = 10;
var boxYSpace:int = 10;
 
function addGameBoard():void {
	// create a board to display all of the square buttons on
	var gb:Sprite = new Sprite();
	gb.graphics.beginFill(0xFFFFFF);
 
	// since the entire grid is at most 6x6, make enough room
	gb.graphics.drawRect(0,0,6*boxWidth+7*boxXSpace,6*boxHeight+7*boxYSpace);
	gb.graphics.endFill();
 
	gb.name = "gameBoard"
	gb.x = 20;
	gb.y = 20;
 
	this.addChild(gb);
}
 
function removeGameBoard():void {
 
	// remove the game board and all of the squares on it
	var gb:Sprite=Sprite(this.getChildByName("gameBoard"));
	var thisClip:Sprite;
 
	while(gb.numChildren>0){
		thisClip=Sprite(gb.getChildAt(0));
		thisClip.graphics.clear();
		gb.removeChild(thisClip);
	}
	gb.graphics.clear();
	this.removeChild(gb);
}
 
var onColor = 0xFF3333;
var offColor = 0x333333;
var numberOfRows:int;
var numberOfColumns:int;
var states:Array;
 
function drawBoxes():void {
	// create the squares on the game board
	var gb:Sprite = Sprite(this.getChildByName("gameBoard"));
	var square:Sprite;
 
	// create 3 to 6 rows and 3 to 6 columns
	numberOfRows = Math.floor(Math.random()*4+3);
	numberOfColumns = Math.floor(Math.random()*4+3);
 
	//create the states array, which has the same number of
	//"rows" and "columns" as our grid of squares
	states = new Array(numberOfRows);
 
	for (var i:int = 0; i < numberOfRows; i++) {
	// i = row number
 
		states[i] = new Array(numberOfColumns);
 
		for (var j:int = 0; j < numberOfColumns; j++) {
		// j = column number
 
			// create a square, which is by default 'off'
			square = new Sprite();
			square.graphics.lineStyle(2, 0x000000);
			square.graphics.beginFill(offColor);
			square.graphics.drawRect(0,0,boxWidth,boxHeight);
			square.graphics.endFill();
			states[i][j] = false;
			gb.addChild(square);
 
			// position the square in the correct location
			square.x = (j+1)*boxXSpace + j*boxWidth;
			square.y = (i+1)*boxYSpace + i*boxHeight;
			square.name = "square" + String(i) + String(j);
 
			// add a dynamically created listener for this square
			square.addEventListener(MouseEvent.CLICK,createListener(i,j));
		}
	}
	randomizeGameBoard();
}
 
function createListener(a:int, b:int):Function {
	// dynamically create a listener for the square in position (a,b)
	// that switches the box at (a,b) and the adjacent boxes, and
	// then checks to see if you are done
	var foo:Function = function (evt:MouseEvent):void {
		switchAt(a,b);
		if (checkDone()) {
			tbDoneText.text = "Good job!";
		}
	}
	return foo;
}
 
function invertState(row:int, col:int):void {
	// lookup the square located at (row, col)
	var gb:Sprite = Sprite(this.getChildByName("gameBoard"));
	var thisClip:Sprite = Sprite(gb.getChildByName(("square" + row) + col));
 
	// if the square is off, turn it on, and vice versa
 
	if (states[row][col]) {
		thisClip.graphics.beginFill(offColor);
		thisClip.graphics.drawRect(0,0,boxWidth,boxHeight);
		thisClip.graphics.endFill();
	}
	else {
		thisClip.graphics.beginFill(onColor);
		thisClip.graphics.drawRect(0,0,boxWidth,boxHeight);
		thisClip.graphics.endFill();
	}
	// reverse the state of the square
	states[row][col] = !states[row][col];
}
 
function switchAt(row:int, col:int):void {
	// switch the square that was clicked on
	invertState(row,col);
 
	// switch the squares adjacent to the clicked square
	if (row > 0) {
		invertState(row-1,col);
	}
	if (row < numberOfRows - 1) {
		invertState(row+1,col);
	}
	if (col > 0) {
		invertState(row,col-1);
	}
	if (col < numberOfColumns - 1) {
		invertState(row,col+1);
	}
}
 
function checkDone():Boolean {
	// check to see if all the lights are off
	var bool:Boolean = true;
	var i,j:int;
 
	for (i = 0; i < numberOfRows; i++) {
		for (j = 0; j < numberOfColumns; j++) {
			bool = bool && !states[i][j];
		}
	}
	return(bool);
}
 
function randomizeGameBoard():void {
	// randomly click the game board a random number of times
	// this ensures the game is solvable
	var r:int = Math.floor(Math.random()*5+5);
	var row:int, col:int, i:int;
 
	for (i = 0; i < r; i++) {
		row = Math.floor(Math.random() * numberOfRows);
		col = Math.floor(Math.random() * numberOfColumns);
		switchAt(row,col);
	}
}
 
setupGame();

带拼音的汉语拼音程序源码共享

最近总是有朋友询问我在flash中实现自动识别汉字发音的发音的方法。

我想了想,还是把以前写的那个demo的源码共享出来吧,供大家交流。

源码下载地址:e5a3b0e8b083e6b189e8afade68bbce99fb3e6ba90e7a081

DEMO演示地址:/index.php/archives/181

Deface,一个很不错的图像分析类包

现在国外流行的那个在线化妆的程序就是基于这个类库做的。

演示地址:http://makeover.dailymakeover.com/virtual-makeover/

该项目是开源的,在google code上有下载地址:http://code.google.com/p/deface/

该类库可以根据xml的样本数据定义,找到图片中匹配的内容,比如官方提供的两个demo就是可以找到图片中人物的脸部所在。和在脸部正确的位置安上胡子。

不过通过http下载的代码好像有些旧,通过SVN可以下载到新的代码:http://deface.googlecode.com/svn/trunk/

新的代码作了优化,由于用了fp10支持Vector等新的高效处理方法,代替了以前的Array的遍历,效率上有很大提高。需要FLEX SDK 4.0.0以上版本支持,或者Flash CS4支持。

很不错,大家试试。

as3图片万能切割类[下载]

最近在做一个图像处理的东西,需要对图片进行随意的切割,于是在网上发现了这样一个类包。

这个类包里面把对图片的简单操作都实现了,包括切图,包括对图片的滤镜效果,图片的色相、饱和度、明暗等等。很不错的东东。

源文件下载:bmpcuter

利用SampleDataEvent模拟出的8位机音乐源码示例

最近在国外的一个网站上看到一个示例,只有2K大小的一个swf文件播放出了长达十分钟左右的游戏音乐。很是惊讶。于是仔细研究了下源码,发现是用的fp10中的新功能。在fp10新的API中有个SampleDataEvent的类,结合Sound对象可以播放出动态的音乐。
比如下面这段代码就可以播放出简单的正弦波。在FLEX SDK3.2以上版本,或者Flash CS4中可以测试。

var mySound:Sound = new Sound();
function sineWaveGenerator(event:SampleDataEvent):void {
    for ( var c:int=0; c<8192; c++ ) {
        event.data.writeFloat(Math.sin((Number(c+event.position)/Math.PI/2))*0.25);
        event.data.writeFloat(Math.sin((Number(c+event.position)/Math.PI/2))*0.25);
    }
}
 
mySound.addEventListener(SampleDataEvent.SAMPLE_DATA,sineWaveGenerator);
mySound.play();

Adobe官方中文手册中关于这个类的介绍:

http://livedocs.adobe.com/flex/3_cn/langref/flash/events/SampleDataEvent.html

下面的是这个牛B的8位机音乐源码:8位机音乐源码下载

TimelineWatcher类的使用示例

今天在论坛上闲逛时发现了这个好东西,TimelineWatcher:一个不错的工具类。

用这个类可以做到侦听一个MovieClip播放情况,比如可以做到让MovieClip播放到哪个桢,派发事件等等。很实用。

收集到网上的示例源码,提供下载,服务于大众:

点击下载:timelinewatcher

这个示例上是个左右移动的小球,左上角的一个文本可以实时显示这个小球动画播放到的桢标签,以及循环的次数。

Flash预览本地图片,简单源文件示例

最近要做个flash上传图片的东东,其中有个效果是先让用户在本地预览一下图片,然后再点击上传。

本来想当然的以为这个功能很简单就能实现,用UILoader直接Load一下本地的图片就行了。后来再一想,不对!有两个难点:1.FileRefrence只能拿到File的name,拿不到File的Path。2.即便是拿出了File的Path,在网页上运行的File也不可能跨过安全沙箱访问本地的文件。

但是我的确看到有人做出来过的,这是怎么回事呢?

Baidu了一下后知道了,原来可以利用FlashPlayer10中的新东东,FileRefrence.load()和FileRefrence.data,把图片数据以二进制的形式读入Flash,然后直接用Loader.loadBytes()方法读入二进制数据,直接显示到界面上。

这里面有个问题要注意,由于这是Flash Player 10新支持的东东,如果是用Flash开发的,需要用Flash CS4开发,并将Flash Player选成10的版本,如果是用Flex开发,需要SDK  4.0以上版本。

一个简单的例子及源文件:

示例源文件下载