アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

Flash内で作成した複数画像を同時にアップロードする

こんにちは、中川です。

つい最近、「Flashで作成した画像(jpg)をサーバ側にアップロードする」ということが必要になることがありました。
普通に画像1個であれば簡単なのですが、今回は複数同時にアップしたいという状況でした。

連続してのアップロードや、zip圧縮、画像を結合してなど様々な方法を教えていただいたりしたのですが、サーバ側の処理をいかに通常処理、かつ楽するかの部分でいろいろ探したところ、
「HTTPPostBinary」というas3のライブラリで実現することができそうですので、ご紹介したいと思います。
こちらを利用するとAS側のプログラムも特に面倒ということもなさそうです。

それでは、早速試してみましょう。

HTTPPostBinary class connects your flash program to general webservice」から「HTTPPostBinary.as」をダウンロードしてFlexプロジェクト内に配置します。

で、実際に使いかたも、上記ブログ記事のとおり、



var loader:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest("http://www.flickr.com/tools/uploader_go.gne");
var httpdata:HTTPPostBinary = new HTTPPostBinary();
httpdata.addBinary("photo", jpegDat, "image/jpeg", "snap.jpg");
request.contentType = httpdata.contentType;
request.method = httpdata.method;
request.data = httpdata.encodeData();
loader.load(request);


このように簡単に利用できます。

以下、ボタンを押したら2種類のサイズの画面イメージをサーバにPOSTするサンプルです。
今回のサンプルの構成は以下のようになっています。



UploadFlex.mxml


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[

			import mx.graphics.codec.JPEGEncoder;
			import ym.net.HTTPPostBinary;
			
			public function upload():void { 
				
				//1個目の画像
				var bmd:BitmapData = new BitmapData(100, 200, false, 0xFFFFFF);
				bmd.draw(this);
				var encoder1:JPEGEncoder = new JPEGEncoder(100);
				var bytes1:ByteArray = encoder1.encode(bmd);
				
				//2個目の画像
				var bmd2:BitmapData = new BitmapData(50, 50, false, 0xFFFFFF);
				bmd2.draw(this);
				var encoder2:JPEGEncoder = new JPEGEncoder(100);
				var bytes2:ByteArray = encoder2.encode(bmd2);
				
				var loader:URLLoader = new URLLoader();
				var request:URLRequest = new URLRequest("/sample/post.php");
				var httpdata:HTTPPostBinary = new HTTPPostBinary();
				
				//画像を添付
				httpdata.addBinary("img1", bytes1, "image/jpeg", "img1.jpg");
				httpdata.addBinary("img2", bytes2, "image/jpeg", "img2.jpg");
				
				//テキストデータも同時に送信してみる
				httpdata.addString("hoge", "test string");				
				
				request.contentType = httpdata.contentType;
				request.method = httpdata.method;
				request.data = httpdata.encodeData();
				
				//送信
				loader.load(request);
			
			}
			
		]]>
	</mx:Script>
	<mx:Button click="upload()" label="upload" />
</mx:Application>


手元のFlexBuilderでの作成が手軽だったので、Flexプロジェクトとして作成していますが、
通常のASプロジェクトでもHTTPPostBinary自体の動作には影響なく動くでしょう。

そして、受け取る側のphpコードはおなじみの$_POST, $_FILESで大丈夫です。

post.php


<?php

/*
■UploadFlex.swfから以下のようなデータがPOSTされてくる

$_POST = Array
(
    [hoge] => test string
)

$_FILES = Array
(
    [img1] => Array
        (
            [name] => img1.jpg
            [type] => image/jpeg
            [tmp_name] => /tmp/phpD7lTa9
            [error] => 0
            [size] => 4873
        )

    [img2] => Array
        (
            [name] => img2.jpg
            [type] => image/jpeg
            [tmp_name] => /tmp/php7V23q5
            [error] => 0
            [size] => 2733
        )

)

*/

error_log(print_r($_POST, true), 3, '/tmp/hoge.txt');
error_log(print_r($_FILES, true), 3, '/tmp/hoge.txt');

//uploadディレクトリにPOSTされたファイルを保存
foreach ($_FILES as $key => $file) {
    if ($file['error'] == UPLOAD_ERR_OK) {
        $tmp_name = $file["tmp_name"];
        $name = $file["name"];
        move_uploaded_file($tmp_name, "./upload/".$name);
    }
}


実際にアップロードされた画像ファイルが以下の2個となります。
  
※ボタンだけを配置したFlashのキャプチャをしているため、見た目はアレですが、、、ちゃんと、指定した2種類のサイズで切り抜いて作成されています。


まだ、ちゃんとした検証はしてないですが、最新のFlash10のバージョンでは、手元のIE6, IE7, IE8, Firefox3.5では複数画像もPOSTデータも正常にサーバ側で受け取ることができました。