All posts by Aymeric

About Aymeric

Freelance Interactive & Game Developer.

Webcam picture cutout

In many websites, for a most immersive surf you take a shot of your face. Often, it is simply a red square. You move your head in, and you take the picture; it is really easy to do. However if you want to take only the head with a circle for exemple it’s a bit more difficult.

This is a script to do that (on the website, the swf is opened with a lightbox and the picture is saved) :

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
package {
 
	import com.adobe.images.PNGEncoder;
 
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.external.ExternalInterface;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestHeader;
	import flash.net.URLRequestMethod;
	import flash.utils.ByteArray;
 
        /**
	 * @author Aymeric
	 */
 
	public class CaptureTete extends Sprite {
 
		public var button:Sprite;
 
		private var _cam:Camera;
		private var _video:Video;
 
		private var _bitmapData:BitmapData;
		private var _bitmap:Bitmap;
 
		private var _conteneur:Sprite;
		private var _drawPanel:Sprite;
 
		public function CaptureTete() {
 
			_cam = Camera.getCamera();
			_video = new Video(320, 240);
 
			_bitmapData = new BitmapData(_video.width, _video.height);
			_bitmap = new Bitmap(_bitmapData);
 
			_video.attachCamera(_cam);
			_video.x = _bitmap.x = 20;
			_video.y = _bitmap.y = 40;
 
			addChild(_video);
 
			_conteneur = new Sprite();
			addChild(_conteneur);
 
			_drawPanel = new Sprite();
			_drawPanel.graphics.clear();
			_drawPanel.graphics.lineStyle(2, 0xeea41e);
			_drawPanel.graphics.beginFill(0xDEFACE, 0);
			_drawPanel.graphics.drawCircle(80, 80, 80);
			_drawPanel.graphics.endFill();
			_conteneur.addChild(_drawPanel);
			_drawPanel.x = 100;
			_drawPanel.y = 100;
 
			button.buttonMode = true;
			button.addEventListener(MouseEvent.CLICK, _captureImage);
		}
 
		private function _captureImage(e:MouseEvent):void {
 
                        button.removeEventListener(MouseEvent.CLICK, _captureImage);
 
			_bitmapData.draw(_video);
			_conteneur.addChild(_bitmap);
 
			_conteneur.setChildIndex(_drawPanel, _conteneur.numChildren - 1);
 
			_cam = null;
			removeChild(_video);
			_video = null;
 
			_bitmap.mask = _drawPanel;
 
			_bitmapData = new BitmapData(320, 240,true,0x000000);
			_bitmapData.draw(_conteneur);
 
			var bitmap:Bitmap = new Bitmap(_bitmapData);
			_conteneur.addChild(bitmap);
 
			var bmd:BitmapData = new BitmapData(160, 160);
			var rect:Rectangle = new Rectangle(100, 100, 160, 160);
			bmd.copyPixels(_bitmapData, rect, new Point(0, 0));
 
			var pngStream:ByteArray = PNGEncoder.encode(bmd);
 
			var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
 
			var savePNG:URLRequest = new URLRequest("save.php");
			savePNG.requestHeaders.push(header);
			savePNG.method = URLRequestMethod.POST;
			savePNG.data = pngStream;
 
			var urlLoader:URLLoader = new URLLoader();
			urlLoader.load(savePNG);
 
			urlLoader.addEventListener(Event.COMPLETE, _loaded);
		}
 
		private function _loaded(evt:Event):void {
 
			evt.target.removeEventListener(Event.COMPLETE, _loaded);
			ExternalInterface.call("closeLightbox");
		}
	}
 
}

You can found the external library made by Mike Chambers : as3corelib.

The Php script to save it :

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
 
if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) {
 
	$png = $GLOBALS["HTTP_RAW_POST_DATA"];
	$img = $_GET["img"];
	$filename = "images/img_". mktime(). ".png";
	file_put_contents($filename, $png);
} else {
	echo "Encoded PNG information not received.";
}
 
?>

To go further, we can draw our own circle or an other shape. Using a Php Session for the filename is cool too !
Exemple (don’t worry, I do not save ! 😉 )

Beat the bot

At the Gobelins school, we made a game in less than 5 days. The concept was to create a musical and memory game : a sequencer. We worked in pairs : a developper and a graphic designer, he did a great job !

To developp the game I used the Gaia Framework and made MVC design pattern ! Gaia saves me some precious time : preloader, external loading, swfadress, transition between pages ; and MVC helps cleaning my code.

The game : Beat the bot !

Recently I’m trying to syncrhonize an iPhone with a website using BlazeDS on Google App Engine. I just need to find how can I export a flex project into an ipa… Hope it will be soon ok !

Flash Circle Preloader

A beautiful preloader is important for a flash website. Indeed, if you need to load much data, your preloader will be visible all during this time. And if it is not interssant, visitors may leave your website.

Here are some examples of interesting preloader : http://www.prettyloaded.com.

Most often, preloader are made by graphic designer on 100 frames without using any code.
Developpers integrate them, and use gotoAndStop on an enterFrame to display the loading progression.

This is my circle preloader.
To make this, I used 2 masks moving like the circle. Of course it could be done with code, but it would be a headlock with cosinus and sinus !
You can find the source here.

Playing with Blend Mode

Recently, I tried some BlendMode in AS3. Thanks to them we can reproduce some cool effects of Photshop.
This is a simple script to do that. I thought it’s a nice effect !

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
package {
 
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.geom.Point;
 
	[SWF(backgroundColor="#000000", frameRate="31", width="600", height="500")]
 
	/**
	 * @author Aymeric
	 */
 
	public class MouseFollower extends Sprite {
 
		private var _container:Sprite;
 
		private var _bData:BitmapData;
		private var _img:Bitmap;
		private var _circle:Shape;
 
		public function MouseFollower() {
 
			_container = new Sprite();
                        _container.visible = false;
			this.addChild(_container);
 
			_bData = new BitmapData(600, 500, true, 0x00FF00);
 
			_img = new Bitmap(_bData);
 
			_circle = new Shape();
 
			this.addChild(_img);
 
			_container.addChild(_circle);
 
			this.addEventListener(Event.ENTER_FRAME, _ef);
		}
 
		private function _ef(evt:Event):void {
 
			_circle.graphics.clear();
			_circle.graphics.beginFill(Math.random()*0xFFFFFF);
			_circle.graphics.drawCircle(0, 0, 10);
			_circle.graphics.endFill();
 
			var diffx:int =	mouseX - _circle.x;
			var diffy:int = mouseY - _circle.y;
 
			_circle.x +=diffx * 0.05;
			_circle.y +=diffy * 0.05;
 
			_bData.draw(_container, null, null, BlendMode.ADD);
			_bData.applyFilter(_bData, _bData.rect, new Point(), new BlurFilter(5, 5, 2));
		}
	}
}

This two lines are important if you want to keep an eye on your CPU usage :
_circle.graphics.clear();
_circle.graphics.endFill();
BlendMode are more than ever CPU’s eater !

Flash template for publishing with SWF Object

Publishing for the web inside Adobe Flash IDE is a bit outdated : nowadays we use SWF Object to embed our swf.
So this is a template that you can add into the Flash IDE to allow SWF Object publishing, thanks to Pierrick for the discovery !

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
$TTSWFObject
$DXDefaultDetection.html
$DS
Display Adobe Flash Movies with SWFObject. NOTE: You Must add swfobject.js and expressInstall.swf in the same directory as your swf.
$DF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
	<head>
		<title>$TI</title>
		$CS
		<script type="text/javascript" src="js/swfobject.js"></script>
		<script type="text/javascript">
 
			var flashvars = {};
 
			var params = {};
			params.menu = "$ME";
			params.quality = "$QU";
			params.scale = "$SC";
			params.salign = "$SA";
			params.wmode = "$WM";
			params.bgcolor = "$BG";
			params.allowfullscreen = "false";
			params.allowscriptaccess = "sameDomain";
 
			var attributes = {};
			attributes.id = "$TI";
			attributes.name = "$TI";
			attributes.align = "$HA";
 
			swfobject.embedSWF("$TI.swf", "$TIDiv", "$WI", "$HE", "$FV,$JR,$NR", "expressInstall.swf", flashvars, params, attributes);
		</script>
	</head>
 
	<body bgcolor="$BG">
 
	 <style type='text/css'>
	* {height:100%; margin:0; padding:0;}
	 </style>
		<center>
		<div id="$TIDiv">
			<a href="http://www.adobe.com/go/getflashplayer">
				<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
			</a>
		</div>
		</center>
	</body>
</html>

Save your file as “swfobject.html” into the directory :
Mac Users : /Users/YourName/Library/Application Support/Adobe/Flash CS5/fr_FR/Configuration/HTML/
Windows : C:\Users\YourName\AppData\Local\Adobe\Flash CS5\fr_FR\Configuration\Commands\HTML\

Open Flash, check parameters of publication for HTML and choose SWFObject for the model. Then publish, your swf should be embed with SWFObject into your html.

P.S. Don’t forget to change your charset into UTF-8

Dynamic variable in AS3

An other short practical script to access to dynamic variable into a loop :

var fiole1:Fiole1, fiole2:Fiole2, fiole3:Fiole3, fiole4:Fiole4, fiole5:Fiole5;
for (var i:uint = 1; i < 6; ++i) {
 
	this["fiole" + i].addEventListener(MouseEvent.MOUSE_OVER, _over);
	this["fiole" + i].addEventListener(MouseEvent.MOUSE_OUT, _out);
}

Box2D with the WorldConstructionKit

Before the weekend, I suggest to dig into the Box2D API for Flash with the great WorldConstructionKit.
Box2D is a physical engine wrote in C++ and translated into many languages such as Java, Objective-C, AS3, JavaScript…

For ActionScript3, there are 2 ports : Boris the brave’s port, and the WCK. You can find a performance comparison here made by Allan Bishop.
The WCK is the best thanks to the Alchemy port : it translates the C++ into something which can be understable by Flash. More information here.

The WCK provides a “a toolset / framework for rapidly developing physics based games / websites within the Flash IDE. WCK allows you to layout your 2d worlds / game levels entirely within Flash and have them hook into the physics simulation without writing any code.”

Continue reading Box2D with the WorldConstructionKit

htaccess redirect to www

Using AMFPhp, you may have domain’s SecurityErrorEvent with the Sandbox due to the presence of the www or not.

Here are two lines for your .htaccess :

RewriteEngine ON
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$   http://www.%{HTTP_HOST}/$1  [L,R=301]

Php’s print_r for as3

Here is really useful class tools for as3 based on php function found on http://dev.base86.com website.

Exemple use :

import com.base86.Tools;
 
var obj:Array = new Array();
obj['a'] = { one: 1, two: 2, three: 3 };
obj['b'] = [ 'one', 'two', [ 'three' ] ];
obj['c'] = new MovieClip();
 
Tools.pr(obj);

The console will display:

(array) {
	[a] => (object) {
		[two] => (number) 2
		[three] => (number) 3
		[one] => (number) 1
	}
	[b] => (array) {
		[0] => (string) one
		[1] => (string) two
		[2] => (array) {
			[0] => (string) three
		}
	}
	[c] => (object) [object MovieClip]
}

And the class now :

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
package com.base86 {
	public class Tools {
		/**
		 * An equivalent of PHP's recursive print function print_r, which displays objects and arrays in a way that's readable by humans
		 * @param obj    Object to be printed
		 * @param level  (Optional) Current recursivity level, used for recursive calls
		 * @param output (Optional) The output, used for recursive calls
		 */
		public static function pr(obj:*, level:int = 0, output:String = ''):* {
			if(level == 0) output = '('+ Tools.typeOf(obj) +') {\n';
			else if(level == 10) return output;
 
			var tabs:String = '\t';
			for(var i:int = 0; i < level; i++, tabs += '\t') { }
			for(var child:* in obj) {
				output += tabs +'['+ child +'] => ('+  Tools.typeOf(obj[child]) +') ';
 
				if(Tools.count(obj[child]) == 0) output += obj[child];
 
				var childOutput:String = '';
				if(typeof obj[child] != 'xml') {
					childOutput = Tools.pr(obj[child], level + 1);
				}
				if(childOutput != '') {
					output += '{\n'+ childOutput + tabs +'}';
				}
				output += '\n';
			}
 
			if(level == 0) trace(output +'}\n');
			else return output;
		}
 
		/**
		 * An extended version of the 'typeof' function
		 * @param 	variable
		 * @return	Returns the type of the variable
		 */
		public static function typeOf(variable:*):String {
			if(variable is Array) return 'array';
			else if(variable is Date) return 'date';
			else return typeof variable;
		}
 
		/**
		 * Returns the size of an object
		 * @param obj Object to be counted
		 */
		public static function count(obj:Object):uint {
			if(Tools.typeOf(obj) == 'array') return obj.length;
			else {
				var len:uint = 0;
				for(var item:* in obj) {
					if(item != 'mx_internal_uid') len++;
				}
				return len;
			}
		}
	}
}