ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
メインメニュー
フォーラム一覧   -   トピック一覧
   ActionScript 3.0
     PHPとの連動について(PHPで画像ファイルを受け取りたい)
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 トピック
tovi
投稿日時: 2006-11-6 20:57
やや お馴染みさん
登録日: 2006-11-6
居住地:
投稿: 4
PHPとの連動について(PHPで画像ファイルを受け取りたい)
PHPとの連動について質問です。

クライアントで作成した画像のバイナリデータ(bmp,jpg,pngなど)をPHPに送りたいと考えています。

具体的には、
$_FILES[upFile][name]
のような形で、PHPでデータを取得したいです。

HTMLでいうと
<form enctype="multipart/form-data" action="upload.php" method="post">
<input name="upFile" type="file">
<input type="submit" value="送る">
</form>
という感じで、送ったときと同じ感じで
PHP側でデータを取得したいと考えています。

実現が可能なのか、可能であればその方法を
教えていただけないでしょうか。

注:上記HTMLの例では、クライアント側のファイルを送る感じですが、私が知りたいのは、FLEX2でクライアントのファイルをサーバに送る方法ではなく、自分で作成したBMPなどの画像データをサーバに送る方法です。
説明が下手で、申し訳ありません。よろしくお願いします。
dsh
投稿日時: 2006-11-18 10:58
ご主人様
登録日: 2006-3-29
居住地: 東京
投稿: 296
Re: PHPとの連動について(PHPで画像ファイルを受け取りたい)
toviさん、
引用:
上記HTMLの例では、クライアント側のファイルを送る感じですが、私が知りたいのは、FLEX2でクライアントのファイルをサーバに送る方法ではなく、自分で作成したBMPなどの画像データをサーバに送る方法です。

すいません、
「FLEX2でクライアントのファイルをサーバに送る方法」と「自分で作成したBMPなどの画像データをサーバに送る方法」の違いが分かりませんでした。
…送りたいデータはファイルではないですか? 例えばメモリ上のデータとか。
Crono
投稿日時: 2006-11-20 13:34
ご主人様
登録日: 2006-6-21
居住地: 飯田橋/ヴァナディール
投稿: 229
Re: PHPとの連動について(PHPで画像ファイルを受け取りたい)
以下でFlex2アプリケーション上のオブジェクトのアップロード方を学べると思います:
■Flex2Beta2でのお絵かきツール
http://www.fxug.net/modules/xhnewbb/viewtopic.php?viewmode=flat&order=ASC&topic_id=24&forum=1
・Canvasオブジェクトをどうやって画像ファイルにするの?
・作成した画像ファイルはどうやってサーバーにアップするの?
・(Java等で)サーバーで画像ファイルを受け取るにはどうするの?
あたりが学べると思います。

また、上記お絵かきツールなどのFlexUG製サンプルはSourceForgeにアップされております:
■CVS Repository - directory - SourceForge: flex2
http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/flex2/

PHP版のサーバー処理はまだ上記リンク先に無いかと思いますが(細かくチェックしてません。。。)、サーバーサイドの言語によらず同じような処理で受け取れるかと思います。

【おまけ】
上記リンク先のノウハウの処理途中で出てくるBitmapDataオブジェクトに「サイズ制限」があるのが実案件などではネックになると思います
(巨大画像を扱う場合。。。)
(その際、さらにAS3の「関数1処理60秒制限」がネックになってきます。。。)(両方解決済みではあります。。。ノウハウ要る人いますでせうか?)
tovi
投稿日時: 2006-11-21 19:31
やや お馴染みさん
登録日: 2006-11-6
居住地:
投稿: 4
Re: PHPとの連動について(PHPで画像ファイルを受け取りたい)
送りたいデータはファイルではありません
FLEX2のBMPのオブジェクトです。

説明が下手で申し訳ありません。
tovi
投稿日時: 2006-11-21 19:34
やや お馴染みさん
登録日: 2006-11-6
居住地:
投稿: 4
Re: PHPとの連動について(PHPで画像ファイルを受け取りたい)
詳細な解説ありがとうございました。
私が望んでいるのも、ほぼ上記のサンプルのような感じです。

それをjavaではなく、PHPで行う方法を望んでいます。

引用:

・Canvasオブジェクトをどうやって画像ファイルにするの?
・作成した画像ファイルはどうやってサーバーにアップするの?

というところはもう理解したのですが、そこからさきの

・PHPでサーバーで画像ファイルを受け取るにはどうするの?

という部分がわからなく困っています。
Crono
投稿日時: 2006-11-22 11:23
ご主人様
登録日: 2006-6-21
居住地: 飯田橋/ヴァナディール
投稿: 229
Re: PHPとの連動について(PHPで画像ファイルを受け取りたい)
(前提、私はPHP歴数分です)
こんにちは、くろのです。以下、非常に長々すいません。

PHPでのファイルアップロード関連情報を漁ってみました(下記リンクをちょと調べてみてください)

■FlexUGでのKENさんの投稿
http://www.fxug.net/modules/xhnewbb/viewtopic.php?topic_id=436
(返答がまだ来ていません)

■flexcoders : Enterprise RIA Development with Macromedia Flex
http://tech.groups.yahoo.com/group/flexcoders/
(この掲示板に質問して困った時は次はココ)

■How up upload a ByteArray to PHP on the server?
http://tech.groups.yahoo.com/group/flexcoders/message/38654
(PHP、JPEGEncoderで検索した際のヨサゲな投稿@Yahoo!掲示板)
(この投稿のレスは詳細には読んでいません。。。)

■Chapter 38. Handling file uploads
http://us3.php.net/manual/en/features.file-upload.php
(PHP本家のファイルアップロードに関して)

■KENさんの投稿で示されていたPHPでByteArrayを送る方法を示しているサイト
http://blog.je2050.de/?p=69



※Byte配列をサーバーにアップロードするとは※
Flex2、ActionScript3でdata:ByteArrayを送る際、
以下のようにするサンプルが多いと思います:

myRequest.data = data;(1)

この式により、HTTPリクエストのデータ部全体にByte配列が格納されます。

本来ならクライアントは、ファイルアップロード機能標準(RFC1867※1)に従ったリクエストを送信するべきです。
Flex2側でこの標準に従う方法がわからない(※2)ですが、上記の方法(1)でも「Java」では直接リクエストのInputStreamからデータを取得することが出来ています。

Struts@Javaだと現在非推奨のBufferedMultipartInputStreamでは取得できて、標準的なJakartaCommonsのFileUploadでは取得できませんでした。

上記のようにどのような言語でも従来用意されている「クライアントのデスクトップにあるようなファイルをHTMLのファイルフォームでアップロードする際に利用するサーバー側モジュール」ではデータをスムーズに取得することが出来ない可能性が高いです。

ではどのようにするとよいかと推測すると、Javaの時のように、「より低レベルの関数やライブラリ」を利用して古典的な感じでHTTPリクエストとやりとりする必要があるかと思います。

(※1 http://www.ietf.org/rfc/rfc1867.txt
(※2 クライアント側で標準に従ったアップロードデータの作成を試みましたが失敗(=ブラウザ内部で行われている処理のシミュレート))


Flex2でサーバーにByteArrayをアップロードする処理(など)を全言語で標準化@FlexUGできればいですね。
(Java、ColdFusion、PHP、Perl、C#、VB、Ruby。。。)

Java(及びColdFusion)の場合、FDSを使えば、上記のすべての問題はすべて簡単に解決されるのですが。。。。。
(Byte配列を引数にする関数を実装するのみ。。。)
otsuka
投稿日時: 2006-11-22 12:52
やや お馴染みさん
登録日: 2006-7-10
居住地: tokyo
投稿: 9
Re: PHPとの連動について(PHPで画像ファイルを受け取りたい)
引用:
(※2 クライアント側で標準に従ったアップロードデータの作成を試みましたが失敗(=ブラウザ内部で行われている処理のシミュレート))
自分でもこういう処理のスクリプトを作れないかなあと考えていたのですが、どういう理由で失敗してしまったのか、よかったら教えていただけますでしょうか。
Crono
投稿日時: 2006-11-22 13:36
ご主人様
登録日: 2006-6-21
居住地: 飯田橋/ヴァナディール
投稿: 229
Re: PHPとの連動について(PHPで画像ファイルを受け取りたい)
デスクトップ上のPNGファイルをHTMLのファイルフォームでアップロードした場合に実際にネットワーク上のリクエストデータは何が流れているかをモニタリング。すると、
http://www.ietf.org/rfc/rfc1867.txt
に記述されているような内容が出てきました。

それを下記のようにシミュレートしてみたところ失敗:

(以下のdataが画像データのByte配列)
var separator:String = "---------------------------7d64e372b0618";
var reqData:String = "--" + separator + "\r\n";
reqData = reqData + "Content-Disposition: form-data; name=\"hogehoge\"; filename=\"hogehoge.png\"" + "\r\n";
reqData = reqData + "Content-type: image/x-png" + "\r\n" + "\r\n";
reqData = reqData + data.readUTF() + "\r\n"; ← この行をいろいろやってみましたが想定の結果にならず。。。
reqData = reqData + "--" + separator + "--"
myURLRequest.data = reqData;


おまけ。こういうのを考え始めると、以下のような事も思いついてきます:

・上記のようにしないでも「複数ファイル同時アップロード」は可能(アップロードボタンクリック後、ASでリクエストの送信を制御。ただし、複数リクエスト)
・ブラウザの処理を真似できるようになると、特にサーバー側で特殊な事をしなくてよくなるな
・画像を半分アップロードしたところで失敗したら、後半半分からアップロードしなおしてみる(非連続接続(OCC))といった処理をFDSなしでごりごりやるにはどうしたらよいのだろう???
・Flex2やApolloでオリジナルブラウザを作成するにはここらへんの処理が重要なんで無いの?
(Flex2内部で作成したファイルのサーバー及びクライアントへの保存)

限が無いのでここらへんでw
dsh
投稿日時: 2006-11-22 14:52
ご主人様
登録日: 2006-3-29
居住地: 東京
投稿: 296
Re: PHPとの連動について(PHPで画像ファイルを受け取りたい)
toviさん、

引用:
というところはもう理解したのですが、そこからさきの

・PHPでサーバーで画像ファイルを受け取るにはどうするの?

という部分がわからなく困っています。

出来ました! ソースをそのまま投稿します。

・サーバ側(PHP - 動作確認はPHP5.2.0でしました)
raw_upload_handler.php
<?php

// file_get_contentsは、PHP 4.3.0以降に存在
// 注意: php://input は、 enctype="multipart/form-data" に対しては使用できない
// 参照: http://jp.php.net/wrappers.php
$png = file_get_contents("php://input");

$fp = fopen('test.png', 'wb');
fwrite($fp, $png);
fclose($fp);
?>


・クライアント側(Flex2)
BitmapDataUploader.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[

import mx.core.Application;
import mx.core.UIComponent;
import PNGEncoder;


private function upload():void {
	//-- your byte array you want to save
	var pngEncoder:PNGEncoder = new PNGEncoder();
	var bytes:ByteArray = pngEncoder.encode(getBitmapData(UIComponent(Application.application)));

	//-- set up correct url request using post in binary mode
	var request:URLRequest = new URLRequest('http://localhost/flex/raw_upload_handler.php');
	var loader: URLLoader = new URLLoader();
	request.contentType = 'application/octet-stream';
	request.method = URLRequestMethod.POST;
	request.data = bytes;

	loader.load(request);
}

private function getBitmapData(component:UIComponent):BitmapData
{
	var b:BitmapData = new BitmapData(component.width, component.height);
	b.draw(component, new Matrix());

	return b;
}

]]></mx:Script>

	<mx:VBox backgroundColor="blue" width="200" height="200" 
		verticalAlign="middle" horizontalAlign="center">
		<mx:Button label="test test test"/>
	</mx:VBox>
	
	<mx:Button label="upload" click="upload()"/>
</mx:Application>

・クライアント側(Flex2)
PNGEncoder.as
(※元のソース:
http://www.mail-archive.com/flexcoders@yahoogroups.com/msg24056/PNGEncoder.as
コンパイルが通るよう微修正)
package {

	import flash.display.*;
	import flash.geom.*;
	import flash.net.*;
	import flash.utils.ByteArray;
	
	
public final class PNGEncoder {
	
	
	private var _png:ByteArray;
	
	public function encode(img:BitmapData):ByteArray
	{

		var imgWidth:uint = img.width;
		var imgHeight:uint = img.height;

		var imgData:ByteArray = img.getPixels(new Rectangle(0,0,imgWidth,imgHeight));
				
		_png = new ByteArray();
		
		_png.writeByte(137);
		_png.writeByte(80);
		_png.writeByte(78);
		_png.writeByte(71);
		_png.writeByte(13);
		_png.writeByte(10);
		_png.writeByte(26);
		_png.writeByte(10);
		
		var IHDR:ByteArray = new ByteArray();
		IHDR.writeInt(imgWidth);
		IHDR.writeInt(imgHeight);
		IHDR.writeByte(8); // color depth: 8 bpp
		IHDR.writeByte(6); // color type: RGBA
		IHDR.writeByte(0); // compression: ZLIB
		IHDR.writeByte(0); // filter method
		IHDR.writeByte(0); // not interlaced;
		
		writeChunk([0x49,0x48,0x44,0x52],IHDR);
		
		var IDAT:ByteArray= new ByteArray();
		for(var i:uint=0;i<imgHeight;i++) {
			IDAT.writeByte(0);
			for(var j:uint=0;j<imgWidth;j++) {
				var p:uint = img.getPixel32(j,i);
				IDAT.writeByte((p>>16)&0xFF);
				IDAT.writeByte((p>> 8)&0xFF);
				IDAT.writeByte((p    )&0xFF);
				IDAT.writeByte((p>>24)&0xFF);
			}
		}		
		
		IDAT.compress();
		writeChunk([0x49,0x44,0x41,0x54],IDAT);



		writeChunk([0x49,0x45,0x4E,0x44],null);
		return _png;
	}

	public function dump():String
	{
		_png.position = 0;
		var out:String ="";
		for(var i:uint=0;i<_png.length;i++) {
			var code:String = "0123456789abcdef";
			var v:uint = _png.readUnsignedByte();
			out += code.charAt((v & 0xF0) >> 4);
			out += code.charAt(v & 0xF);
			out += " ";
		}
		return out;
	}
	private function writeChunk(type:Array,data:ByteArray):void
	{
		var len:uint = 0;
		if(data != null)
			len = data.length; // data length
		_png.writeUnsignedInt(len);

		var p:uint = _png.position;

		_png.writeByte(type[0]);
		_png.writeByte(type[1]);
		_png.writeByte(type[2]);
		_png.writeByte(type[3]);
		if(data != null)
			_png.writeBytes(data);
		
		var endP:uint = _png.position;
		_png.position = p;
		var c:uint = crc(_png,endP-p);
		_png.position = endP;
		_png.writeUnsignedInt(c);
	}

   /* Table of CRCs of all 8-bit messages. */
   private static var crc_table:Array;
   
   /* Flag: has the table been computed? Initially false. */
   private static var crc_table_computed:Boolean = false;
   
   /* Make the table for a fast CRC. */
   private function make_crc_table():void
   {
     var c:uint;
     var n:int;
     var k:int;
   
   	 crc_table = [];
   	 
     for (n = 0; n < 256; n++) {
       c = n;
       for (k = 0; k < 8; k++) {
         if (c & 1)
           c = uint(uint(0xedb88320) ^ uint(c >>> 1));
         else
           c = uint(c >>> 1);
       }
       crc_table[n] = c;
     }
     crc_table_computed = true;
   }
   
   /* Update a running CRC with the bytes buf[0..len-1]--the CRC
      should be initialized to all 1's, and the transmitted value
      is the 1's complement of the final running CRC (see the
      crc() routine below)). */
   
   private function update_crc(crc:uint, buf:ByteArray,
                            len:uint):uint
   {
     var c:uint = crc;
     var n:int;
	var v:uint;
	   
     if (!crc_table_computed)
       make_crc_table();
     for (n = 0; n < len; n++) {
     	v = buf.readUnsignedByte();
       c = uint(crc_table[(c ^ v) & uint(0xff)] ^ uint(c >>> 8));
     }
     return c;
   }
   
   /* Return the CRC of the bytes buf[0..len-1]. */
   private function crc(buf:ByteArray, len:uint):uint
   {
     var cc:uint = update_crc(uint(0xffffffff), buf, len);
     return uint(cc ^ uint(0xffffffff));
   }	
	
}
}
tovi
投稿日時: 2006-11-24 18:53
やや お馴染みさん
登録日: 2006-11-6
居住地:
投稿: 4
Re: PHPとの連動について(PHPで画像ファイルを受け取りたい)
皆さんありがとうございました
いろいろ調査してみます。

一応、自分のほうも出来るにはできました

<?php
$fileName = "test.jpg";
$fp = fopen($fileName, 'wb');
fwrite($fp, $GLOBALS['HTTP_RAW_POST_DATA']);
fclose($fp);
?>

-------------------

var request:URLRequest = new URLRequest(URL);
request.contentType = "application/octet-stream";
request.method = URLRequestMethod.POST;
request.data = pixels;

sendToURL(request);

pixelsはbytearrayです。

ただ、Formでおくったみたいに、ファイル名とかがつかないのが嫌なんですよね・・・。
画像以外の情報も含めるとなると、自分のやり方ではだめですし・・・。

ちょっと時間がないので、時間ができたらまた挑戦してみます。
ありがとうございました。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を