Category Archives: Php

Resize icons for mobile apps

There are things which take times, they could easily be automated but there aren’t. One of this task is to generate all the icons for a mobile application. You have to resize the same image into 10 different sizes, for Android and iOS (29, 36, 48, 50, 57, 58, 72, 100, 114, 512, 1024).

Why Apple doesn’t only require an image size of 1024 and automatically generate the smaller picture when the app is exported for the publication? There may be a good reason for that. Anyway, go to this Github and grab the php script to generate app icons for Android & iOS in all requested resolutions.

Now the quick dev story: at first, I thought it was a good small project to get back into some ruby dev. I didn’t practice it since several years ago. So I started with Sparrow’s samples, but quickly I went into library & version nightmare, and I wasn’t able to remember a single line of ruby! So I get back to php very quickly and discover that we may use it with a CLI (why couldn’t we?). It’s very quick & powerful, be ready for some script for renaming 😀

Edit:
Find some scripts for renaming files and delete others one based on a string name: https://github.com/alamboley/AssetsOperations

Using native Php with haXe Php

Recently I had some time to dig more with haXe Php. The major question was how does it integrate with existing native Php ? I’m glad to say that it works fine!
Let’s start a quick overview of our native Php file test (Simple.class.php) :

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
<?php
function makeSimple($text) {
    return new Simple($text);
}
 
function affichText($text) {
    echo $text;
}
 
class Simple {
 
    public $text;
    public $tab;
 
    public function __construct($text) {
        $this->text = $text;
        $this->tab[0] = "index 0";
        $this->tab[1] = "index 1";
    }
 
    public function doPrint() {
        echo $this->text;
    }
 
    protected function changeText($text) {
        $this->text = $text;
    }
}
 
class Simple2 extends Simple {
 
    public function __construct($text) {
        parent::__construct($text);
    }
 
    public function makeChange($text) {
        $this->changeText($text);
    }
 
    public function associativeArray() {
 
        $tab["num1"] = "number 1";
        $tab["num2"] = "number 2";
        return $tab;
    }
}
?>

There are a simple function, some inheritance stuff and an associative array which is very common in Php.

Now the haXe part :

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
package;
 
import php.Lib;
 
class Test {
 
    static function main() {
 
    	new Test();
    }
 
    public function new() {
 
        // import php file
    	untyped __call__("require_once", "Simple.class.php");
 
        // call a php function with an arg
    	untyped __call__("affichText", "first msg </br>");
 
        // create a php object with an arg
    	var myPhpObject:Dynamic = untyped __call__('new Simple2', 'second msg </br>');
 
        // manipulate the object
    	myPhpObject.doPrint();
    	myPhpObject.makeChange("some new text </br>");
    	myPhpObject.doPrint();
 
        // print an array
        Lib.print(myPhpObject.tab);
 
        // trace the index 0 value
        trace(myPhpObject.tab[0]);
 
        // make some native php
        untyped __php__("echo '</br>php native from haXe !</br>'");
 
        // we need a Hashtable to parse an associative array from php :
        var phpAssociativeArray:Hash<String> = Lib.hashOfAssociativeArray(myPhpObject.associativeArray());
 
        // trace the key value num2
        trace(phpAssociativeArray.get("num2"));
    }
 
}

The output log :

first msg
second msg
some new text
["index 0", "index 1"]Test.hx:32: index 0
php native from haXe !
Test.hx:41: number 2

If you are using everyday libraries/tools written in Php, you may wrap them with haXe for more comfort. Take a look there : Wrapping External PHP Libraries & the haXe Magic.

Unfortunately, there isn’t lots of ressources/tutorials for haXe Php on the website, I will update this post if I go deeper in haXe Php development. It is very pleasant to write Php this way. Give it a try!
haXe API.

And because memes are fashion :

haXe workflow with Sublime Text 2, Php & nme examples

A good IDE is the developer’s best friend. FDT is my favorite one to code AS3 stuff, however I’m not very satisfied with haXe integration… it could be better. A good source code editor is also an amazing tool. I’ve found Sublime Text 2 some months ago, and it sounds always awesome to me. There is an extension which add Package control management to ST2 for adding new plugin, like haXe one.

Come on, download Sublime Text 2, install the Package control and haXe plugins!

That’s ok ? Now we can create a simple Php project.
Create a new file, save it as Test.hx and add this code :

package;
 
class Test {
 
    static function main() {
 
    	new Test();
    }
 
    public function new() {
 
    	var number:Float = 4;
 
        trace(number + 5);
    }
}

Then press ctrl (even if you use a mac) + shift + b. A new file called build.hxml is opened with some code generated to compile. You should just need that :

# Autogenerated build.hxml

# www
-php www
-main Test

Then press ctrl + enter. Your php files are generated. Pretty easy!

Now let’s make more stuff, a PDO connection with a simple query.

var cnx:Connection = PDO.open('mysql:host=localhost;dbname=igobelins', 'myUsr', 'myPwd');

If you press ctrl + space you have some greats auto-completion features! ctrl + i and the class is imported. If you make some mistake your code is highlighted in pink.

Our php stuff :

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
package;
 
import php.db.Connection;
import php.db.Mysql;
import php.db.Object;
import php.db.PDO;
import php.db.ResultSet;
 
class Test {
 
	public var cnx:Connection
 
    static function main() {
 
    	new Test();
    }
 
    public function new() {
 
      cnx = PDO.open('mysql:host=localhost;dbname=igobelins', 'myUsr', 'myPWd');
 
      var sql:String = "SELECT * FROM configs";
 
      var results:ResultSet = cnx.request(sql);
 
      for (result in results) {
       	trace(result.user);
       }
 
       cnx.close();
    }
}

According that you have a field user in your database, it will show the names.

Ok that was pretty cool, what about nme ? Go on this page and download the haXe project. In ST2 go in File/Open Folder… and select the Folder you have just unzipped. It should show the different folders & files in a left panel. Browse the Source and open SimpleBox2DExample.hx and then press ctrl + enter. It is compiled for flash and open quickly the result in the Flash Player. Ok but with NME I would like to target cpp. No problem press ctrl + shift + b then select cpp and compile. This way you can quickly change the target.
He wait, there isn’t html5 target !? I don’t know the reason but it is not offered. But you can add it (thanks to Julien Roche for the tips) : on Mac open the file Users/YourUserName/Library/Application Support/Sublime Text 2/Packages/HaXe/HaxeComplete.py and add html5 to nme_targets on line 124. Restart ST2, press ctrl + shift + b select html5 then compile. You have a new target 😉

Sublime Text 2 and the haXe plugin are awesome, but so far it can not be as powerful as an IDE for debugging. No breakpoint for example, anyway it is already a great tool for a simple code editor!

Recently, JetBrains has released a haXe plugin for IntelliJ. We should keep an eye on it!

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 ! 😉 )

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]