2008.05.16
category
comments

Zip Libraryで複数ファイルを圧縮してみる

テキストファイルをzip圧縮してサーバーに保存してみる。今回はnochump.comのライブラリを使わせてもらう。ここからダウンロードしてクラスパスを通しておく。

流れとしてはまず、ファイル名を任意に決めてバイトストリームにUTF-8ストリングを書き込む。putNextEntry()でファイルにしたいエントリーをぶち込む。write()メソッドで実際のデータを書き込み、zipOut.closeEntry()で閉じる。複数のテキストファイルをまとめてzip圧縮するには、下のコードのように文字列を書き込んだ後にzipOut.closeEntry()をそれぞれに実行してやればよい。後はZipOutputクラスからbyteArrayを取り出してPHPに送信してやるだけ。送信の際はBase64エンコードをかける。

Main.as

ACTIONSCRIPT:
package
{
    import flash.display.Sprite;
    import flash.events.ProgressEvent;
    import flash.events.Event;
    import flash.net.URLRequest;
    import flash.net.URLRequestMethod;
    import flash.net.URLLoader;
    import flash.net.URLVariables;
    import flash.utils.ByteArray;
   
    import mx.utils.Base64Encoder;
    import nochump.util.zip.ZipOutput;
    import nochump.util.zip.ZipEntry;
   
   
    public class Main extends Sprite
    {
        private var url:String = "generateZip.php5";
       
        //------------------------------
        //   コンストラクタ
        //------------------------------
        public function Main()
        {
            var fileName1:String = "helloworld1.txt";
            var fileName2:String = "helloworld2.txt";
            var fileData1:ByteArray = new ByteArray();
            var fileData2:ByteArray = new ByteArray();
            var ze1:ZipEntry = new ZipEntry(fileName1);
            var ze2:ZipEntry = new ZipEntry(fileName2);
            var zipOut:ZipOutput = new ZipOutput();
           
            //-----[ファイル1]
            fileData1.writeUTFBytes("ハローワールド1!");
            zipOut.putNextEntry(ze1);
            zipOut.write(fileData1);
            zipOut.closeEntry();
           
            //-----[ファイル2]
            fileData2.writeUTFBytes("ハローワールド2!");
            zipOut.putNextEntry(ze2);
            zipOut.write(fileData2);
            zipOut.closeEntry();
           
            zipOut.finish();
           
            var zipData:ByteArray = zipOut.byteArray;
            sendZip(zipData);
        }
       
        //------------------------------
        //   zipデータの送信
        //------------------------------
        private function sendZip(byteArr:ByteArray):void
        {
            //-----[Base64エンコード] 
            var enc:Base64Encoder = new Base64Encoder();
            enc.encodeBytes(byteArr);
           
            //-----[送信変数のセット]
            var variables:URLVariables = new URLVariables();
            variables.data = String(enc.flush());
            variables.type = "zip";
           
            //-----[リクエストの発行]
            var urlRequest:URLRequest = new URLRequest();
            urlRequest.url = url;
            urlRequest.method = URLRequestMethod.POST;
            urlRequest.data = variables;
           
            //-----[送信]
            var urlLoader:URLLoader = new URLLoader();
            urlLoader.addEventListener(ProgressEvent.PROGRESS, onProress);
            urlLoader.addEventListener(Event.COMPLETE, onComplete);
            urlLoader.load(urlRequest);
        }
       
       
        //------------------------------
        //   読み込み途中
        //------------------------------
        private function onProress(e:ProgressEvent):void
        {
            trace(e.bytesLoaded + " / " + e.bytesTotal);
        }
       
       
        //------------------------------
        //   読み込み完了
        //------------------------------
        private function onComplete(e:Event):void
        {
            e.target.removeEventListener(ProgressEvent.PROGRESS, onProress);
            e.target.removeEventListener(Event.COMPLETE, onComplete);
           
            trace("complete");
        }
    }
}

PHPではbase64デコードで復元した後に受け取った拡張子でファイルを生成する。zipファイルはdataフォルダの中に出来上がる。解凍してみるとhelloworld1.txtとhelloworld2.txtの2ファイルが展開され、それぞれの文字列が書き込まれている。

generateZip.php5

PHP:
<?php
    $imgdata = base64_decode($_POST['data']);
    $type = $_POST['type'];
    $fileName = time()."-".round(rand(1,10000)).".".$type;
    $fp = fopen("data/".$fileName, 'wb');
    fwrite($fp, $imgdata);
    fclose($fp);
    print $fileName;
?>

最近ちょっとずつバイナリが分かってきて弄れるようになってきた。バイナリ触ってると変に快感があるなー。

2008.05.15
category
comments

PHP経由でBASIC認証を通過する

FlashPlayerのセキュリティー制限でAuthorizationのヘッダーを作成することは禁止されている。swfからBASIC認証を通過するにはいつものごとくPHPとかでproxyするしかないのかな(オーサリング環境からはBASIC認証を通過できる)。以下のコードはswfから「url」、「id」、「pass」をPOST通信でPHPに渡し、BASIC認証を通過する。認証通過後はサーバーから受け取ったデータをechoで出力させてswfに返してやる。これでswfとBASIC認証の先にあるAPIとやり取りできるようになる。

Main.as

ACTIONSCRIPT:
package
package
{
    import flash.display.Sprite;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.net.URLRequestMethod
    import flash.net.URLVariables;
    import flash.events.Event;
    import flash.text.TextField;
   
    public class Main extends Sprite
    {
        private var url:String = "http://***/basicproxy.php";
        private var id:String = "id";
        private var pass:String = "password";
       
        //------------------------------
        //   コンストラクタ
        //------------------------------
        public function Main()
        {
            //-----[送信するデータを格納]
            var variables:URLVariables = new URLVariables();
            variables.id = id;
            variables.pass = pass;
           
            //-----[リクエストの発行]
            var request:URLRequest = new URLRequest();
            request.url = url;
            request.method = URLRequestMethod.POST;
            request.data = variables;
           
            //-----[ローダーの設定]
            var loader:URLLoader = new URLLoader();
            loader.dataFormat = URLLoaderDataFormat.TEXT;
            loader.addEventListener(Event.COMPLETE, onComplete);
            loader.load(request);
        }
       
        //------------------------------
        //   読み込み完了
        //------------------------------
        private function onComplete(e:Event):void
        {
            var loader:URLLoader = e.target as URLLoader;
            loader.removeEventListener(Event.COMPLETE, onComplete);
           
            trace(loader.data);
        }
    }
}

basicproxy.php

PHP:
<?php
    $url = $_POST["url"];
    $id = $_POST["id"];
    $pass  = $_POST["pass"];
   
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_USERPWD, "$id:$pass");
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    $data= curl_exec($ch);
    curl_close($ch);
   
    echo $data;
?>

curlを使うと簡単に認証を通過できる。あとは受け取ったデータを出力するだけ。

2008.05.08
category
comments

GDライブラリが利用できるか確認する方法

レンタルサーバーにPHPのGDが入っているかどうか調べる場合のメモ。PHPファイルに以下を記述して、アップする。ブラウザで確認するとPHPの詳細が表示されるので、この中の「GD Support」が「enabled」になっていれば使用可能。他にも色んな情報が見れる。自分用メモ。

PHP:
<?php
    echo phpinfo();
?>

2008.04.23
category
comments

PHPに複数データを渡してみる

AS3ではURLRequest.dataで送信できるデータは1つなので、複数の変数をPHPに渡したい場合はURLVariablesを使う。URLVariablesをインスタンス化した後に、通常のオブジェクトと同様、任意のプロパティに値を格納していく。ここでは「title」、「url」、「text」の3つの要素を各プロパティに入れている。URLVariablesに格納した後は、URLRequestにて呼び出したいPHPのパスと通信方法を指定(今回はPOST通信)し、URLRequest.dataにURLVariablesを突っ込む。最後にnavigateToURL()でPHPを表示させ、Flashからデータを受け取っているか確認する。

Main.as

ACTIONSCRIPT:
package
{
    import flash.display.Stage;
    import flash.display.Sprite;
    import flash.net.URLVariables;
    import flash.net.URLRequest;
    import flash.net.URLRequestMethod;
    import flash.net.navigateToURL;
   
   
    public class Main extends Sprite
    {
        //------------------------------
        //   コンストラクタ
        //------------------------------
        public function Main()
        {
            sendData();
        }
       
        //------------------------------
        //   データ送信
        //------------------------------
        public function sendData():void
        {
            var variables:URLVariables = new URLVariables();
            variables.title = "5ive.blog";
            variables.url = "http://www.5ive.info/blog/";
            variables.text = "PHPに複数のデータを渡す方法";
           
            var urlRequest:URLRequest = new URLRequest();
            urlRequest.url = "variables.php";
            urlRequest.method = URLRequestMethod.POST;
            urlRequest.data = variables;
           
            //phpに送信
            navigateToURL(urlRequest , "_self");
        }
    }
}

variables.php

PHP:
<?php
    $title = $_POST['title'];
    $url = $_POST['url'];
    $text = $_POST['text'];
   
    echo "title = ".$title."<br />";
    echo "url = ".$url."<br />";
    echo "text = ".$text."<br />";
?>

2007.09.05
category
comments

画像のIPTC情報を取得する

JPEG画像にはExif以外にもIPTCという規格が存在する。検索用キーワードを埋め込んだり、任意のコメントを写真に残したい場合にこれを使う。デジカメで撮った写真にローカルPCでコメント、キーワードを埋め込んで、ファイルをアップロードするだけで自動的にテキスト情報をデータベースに登録みたいな事をしたいので調べてみる。Exif情報を取り出したときとほぼ一緒な感じ。

PHP:
<?php
    $size = GetImageSize (&quot;photo/00001.jpg&quot;, $info);
    $iptc = iptcparse ($info[&quot;APP13&quot;]);
   
    if(isset($info[&quot;APP13&quot;]))
    {
       if(is_array($iptc))
       {
            echo &quot;caption=&quot;.$iptc[&quot;2#120&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;graphic_name=&quot;.$iptc[&quot;2#005&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;urgency=&quot;.$iptc[&quot;2#010&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;category=&quot;.$iptc[&quot;2#015&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;supp_categories=&quot;.$iptc[&quot;2#020&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;spec_instr=&quot;.$iptc[&quot;2#040&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;creation_date=&quot;.$iptc[&quot;2#055&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;photog=&quot;.$iptc[&quot;2#080&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;credit_byline_title=&quot;.$iptc[&quot;2#085&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;city=&quot;.$iptc[&quot;2#090&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;state=&quot;.$iptc[&quot;2#095&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;country=&quot;.$iptc[&quot;2#101&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;otr=&quot;.$iptc[&quot;2#103&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;headline=&quot;.$iptc[&quot;2#105&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;source=&quot;.$iptc[&quot;2#110&quot;][0].&quot;&lt;br /&gt;&quot;;
            echo &quot;photo_source=&quot;.$iptc[&quot;2#115&quot;][0];
        }
    }
?>

2007.08.27
category
comments

サムネイルを生成してみる

PHPでサムネイルを作ってみる。まずは「image」、「thumb」フォルダを作る。photoフォルダにtest.jpgをアップロードしておく。下記のコードでは元画像のサイズを3872×2592、サムネイルのサイズを120×80とする。クオリティを0~100で好みに調整する。(100にしないと画像がざらつく)

あとはこのPHPにアクセスするだけでサムネイルを生成してくれる。アップロード用のPHPにこういった処理を持たせてやると自作フォトログの画像管理が楽になるな。Flashでフォトログのインターフェイス作るよりも、こういった機能周りのコード書くほうが楽しくなってきた。

PHP:
<?php
    $imagePath = "image/";
    $thumbPath = "thumb/";
    $imageName = "test.jpg";
    $imageW = 3872;
    $imageH = 2592;
    $thumbW = 120;
    $thumbH = 80;
    $quality = 100; //jpgの保存品質(0-100)
    $photo = @imagecreatefromjpeg($imagePath.$imageName);
   
    if($photo)
    {
        //-----[サムネイルの領域確保]
        $thumb = imagecreatetruecolor($thumbW, $thumbH);
       
        //-----[画像をリサイズ]
        $result = imagecopyresampled($thumb, $photo, 0, 0, 0, 0, $thumbW, $thumbH, $imageW, $imageH);
       
        //-----[jpgファイルに保存]
        imagejpeg($thumb, $thumbPath.$imageName, $quality);
       
        //-----[メモリの解放]
        imagedestroy($thumb);
        imagedestroy($photo);
       
        echo "<a href=\"$imagePath$imageName\"><img src=\"$thumbPath$imageName\" alt=\"サムネイル\" />";
    }
    else
    {
        echo "画像読み込みエラー";
    }
?>

2007.08.22
category
comments

PHPでExif情報を取得

思った以上に簡単にカメラ機種や撮影時間などのメタデータを取得できた。flickrを使うと自動的にExif情報をゲットできるみたいだけど、自作でフォトビューワーとか作りたい人(自分)のために。以下のExifAll.phpでExif情報の一覧を取得可能。ちなみにデジカメで撮った画像をフォトショで「Web用に保存」してしまうとExif情報が削除されるので注意が必要。

ExifAll.php

PHP:
<?php
    $exif = exif_read_data('img/test.jpg', 0, true);
   
    foreach ($exif as $key => $section)
    {
        foreach ($section as $name => $val)
        {
            echo "$key.$name: $val<br />\n";
        }
    }
?>

続いて欲しい情報だけを取り出すソース。

ExifSelect.php

PHP:
<?php
    $exif = exif_read_data('img/test.jpg', 'IFD0', 1, true);
   
    echo "Make = ".$exif['IFD0']['Make']."<br />\n";
    echo "Model = ".$exif['IFD0']['Model']."<br />\n";
    echo "ExposureTime = ".$exif['EXIF']['ExposureTime']."<br />\n";
    echo "ApertureFNumber = ".$exif['COMPUTED']['ApertureFNumber']."<br />\n";
    echo "ISOSpeedRatings = ".$exif['EXIF']['ISOSpeedRatings']."<br />\n";
    echo "DateTimeOriginal = ".$exif['EXIF']['DateTimeOriginal']."<br />\n";
    echo "ExposureBiasValue = ".$exif['EXIF']['ExposureBiasValue']."<br />\n";
    echo "ExifImageWidth = ".$exif['EXIF']['ExifImageWidth']."<br />\n";
    echo "ExifImageLength = ".$exif['EXIF']['ExifImageLength']."<br />\n";
    echo "WhiteBalance = ".$exif['EXIF']['WhiteBalance']."<br />\n";
    echo "DigitalZoomRatio = ".$exif['EXIF']['DigitalZoomRatio']."<br />\n";
?>

COMPUTED、THUMBNAILおよびCOMMENTのセクションは常に配列となるため、それに合わせる為にexif_read_data()の第3引数を1にする。これで全てのセクションと値を配列として格納するため、2次元配列のカタチで取得できるようになる。詳しくはこちらを参照。

※セクション名の付け方は各メーカーによって異なるようです。上記のソースはNikonのD80で撮影した画像のExif情報を元にしています。他メーカーの場合は一覧を取得するExifAll.phpでセクション名を確認してください。

2007.06.18
category
comments

AMFPHPを試す

AMF通信をやってみる。まずはFlash Remoting用のコンポーネントをダウンロードしてインストールする。

次にamfphpをダウンロード。現時点でのバージョンはamfphp-1.2.6。解凍してamfphpフォルダごとlocalhost直下にアップする。

今回の場合はhttp://localhost/amfphp/browser/index.htmlにアクセスしてデフォルト画面が表示されていればインストール成功となる。この画面がサービスブラウザとなりコードの修正や引数のやりとりを確認する事ができる。ここからはサービス用のphpファイルとflaファイルを作成。

■HelloWorld.php(クラス名とファイル名を統一すること)

PHP:
<?php
class HelloWorld
{
    //-----[AMFPHPのテーブル設定]
    function HelloWorld()
    {
        $this->methodTable = array
        (
            "say" => array
            (
                "access" => "remote",
                "description" => "文字列を返します"
            )
        );
    }
   
    //-----[flashから呼ばれる関数]
    function say($sArgments)
    {
        return 'You said: ' . $sArgments;
    }
}
?>

フラッシュからの引数は$sArgmentsに格納される。このphpをhttp://localhost/amfphp/servicesにアップする。
※この状態でサービスブラウザにアクセスするとHelloWorldがサービスとして登録される。

■HelloWorld.fla(ルートの1フレーム目)

ACTIONSCRIPT:
import mx.remoting.*;
import mx.rpc.*;
import mx.remoting.debug.NetDebug;

var gatewayUrl:String = "http://localhost/amfphp/gateway.php";

NetDebug.initialize();
var _service:Service = new Service(gatewayUrl, null, 'HelloWorld', null , null);
var pc:PendingCall = _service.say("Hello!");
pc.responder = new RelayResponder(this, "handleResult", "handleError");

function handleResult(re:ResultEvent)
{
trace(re.result);
}

function handleError(fe:FaultEvent)
{
trace("エラー");
}

トレースすると"You said: Hello!"が出力される。xmlを経由しなくてもphpとflashでオブジェクトのやりとりが出来るので便利。DBからセレクトしたデータをflashに直接渡したり、phpに配列を渡したりとかなりお手軽にできそう。ここまでくるとMovableTypeとかでxmlを出力してflashに読み込ませるCMS的パターンは壊滅なんじゃないかと。従来のXMLを読み込んでパースかけるやり方よりも高速に送受信ができるらしい。なるほど。

2007.04.12
category
comments

flashとjavascriptとphpでやりとりするには

flashとjavascriptのやり取りは「ExternalInterface」を使う。

JAVASCRIPT:
function getJavascript()
{
   var obj = new Object();
   obj.infoTitle = document.URL;
   obj.infoUrl = document.title;
}

ACTIONSCRIPT:
import flash.external.*;

if(ExternalInterface.available)
{
   infoObj = ExternalInterface.call("getJavascript");
   title.text = infoObj.infoTitle;
   url.text = infoObj.infoUrl;
}
else
{
   title.text = "ExternalInterfaceを利用することが出来ません";
}

javascriptからのデータがinfo.objの中に格納される。

続いて、flashとphpのやり取りは「sendAndLoad」を使う。

PHP:
<?php
   $message= $_POST["message"];
   echo "responce=".$message."をflashに返します";
?>

ACTIONSCRIPT:
//-----[送受信オブジェクトのインスタンス化]
var loadLV:LoadVars = new LoadVars();
var sendLV:LoadVars = new LoadVars();

//-----[渡したい変数名と値を定義]
sendLV.message = "hoge";

//-----[コールバック関数を定義]
loadLV.onLoad = function(success)
{
   if (success == true)
   {
      trace(loadLV.responce);
   }
   else
   {
      trace("通信エラー");   //hogeをflashに返します"
   }
}

//-----[sendAndLoadメソッドを使ってデータの送受信を行う]
sendLV.sendAndLoad("phpファイルのパス", loadLV, "POST");

2007.04.08
category
comments

サイトキャプチャーについて

をやってみる。色々調べるとWindowsサーバーで動く有名なキャプチャアプリがあるらしい。これをサーバーに置いて、phpからコマンドラインでつついてやるだけで驚くほど簡単に実装できる。キャプチャサイズやファイル形式、遅延時間などの細かい設定も可能。出力される画像もかなりキレイ。これでサムネイルを掃き出してくれます。

CrenaHtml2jpg

PHP:
<?php
   $url = $_GET['url'];
   $filename = date('YmdHis').".jpg";
   $cmd = "CrenaHtml2jpg -o$filename -fjpeg -w800x600 -s200x150 -q100 -d72 -t25 -l5 -u$url";
   system($cmd);
   echo <<<EOM
   <img src=$filename>
   EOM;
?>

page 1 / 11