真鍋会に行ってきた

2008 年 6 月 16 日

dsc_3070

rakeemさん主宰の真鍋会に行って来た。初めてお会いする方が多かったので、色々話が聞けて楽しかった。AS3案件が確実に増えてるみたいで、AS2と半々になってきてる人もいるみたい。広告系のスペシャルサイトにがんがん突っ込んでるのが現状で、商品紹介サイトやコーポレートサイトにはまだ波が来てないみたい。他にもiPhoneの話題とか。自分も含め、予約している人が数人いた。静観組もちらほら。2次会では制作の裏話的な話を聞かせてもらったり、Webでモテたいねみたいな。今年は結婚ラッシュになりそうなのか、そういう話をよく聞く。みんなの子供を同級生にして「3才で始めるActionScript」とか。終電までしっかり話が出来ました。

rakeemさん、ありがとうございました。

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

2008 年 5 月 16 日

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

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

Main.as

ACTIONSCRIPT:
  1. package
  2. {
  3.     import flash.display.Sprite;
  4.     import flash.events.ProgressEvent;
  5.     import flash.events.Event;
  6.     import flash.net.URLRequest;
  7.     import flash.net.URLRequestMethod;
  8.     import flash.net.URLLoader;
  9.     import flash.net.URLVariables;
  10.     import flash.utils.ByteArray;
  11.    
  12.     import mx.utils.Base64Encoder;
  13.     import nochump.util.zip.ZipOutput;
  14.     import nochump.util.zip.ZipEntry;
  15.    
  16.    
  17.     public class Main extends Sprite
  18.     {
  19.         private var url:String = "generateZip.php5";
  20.        
  21.         //------------------------------
  22.         //   コンストラクタ
  23.         //------------------------------
  24.         public function Main()
  25.         {
  26.             var fileName1:String = "helloworld1.txt";
  27.             var fileName2:String = "helloworld2.txt";
  28.             var fileData1:ByteArray = new ByteArray();
  29.             var fileData2:ByteArray = new ByteArray();
  30.             var ze1:ZipEntry = new ZipEntry(fileName1);
  31.             var ze2:ZipEntry = new ZipEntry(fileName2);
  32.             var zipOut:ZipOutput = new ZipOutput();
  33.            
  34.             //-----[ファイル1]
  35.             fileData1.writeUTFBytes("ハローワールド1!");
  36.             zipOut.putNextEntry(ze1);
  37.             zipOut.write(fileData1);
  38.             zipOut.closeEntry();
  39.            
  40.             //-----[ファイル2]
  41.             fileData2.writeUTFBytes("ハローワールド2!");
  42.             zipOut.putNextEntry(ze2);
  43.             zipOut.write(fileData2);
  44.             zipOut.closeEntry();
  45.            
  46.             zipOut.finish();
  47.            
  48.             var zipData:ByteArray = zipOut.byteArray;
  49.             sendZip(zipData);
  50.         }
  51.        
  52.         //------------------------------
  53.         //   zipデータの送信
  54.         //------------------------------
  55.         private function sendZip(byteArr:ByteArray):void
  56.         {
  57.             //-----[Base64エンコード] 
  58.             var enc:Base64Encoder = new Base64Encoder();
  59.             enc.encodeBytes(byteArr);
  60.            
  61.             //-----[送信変数のセット]
  62.             var variables:URLVariables = new URLVariables();
  63.             variables.data = String(enc.flush());
  64.             variables.type = "zip";
  65.            
  66.             //-----[リクエストの発行]
  67.             var urlRequest:URLRequest = new URLRequest();
  68.             urlRequest.url = url;
  69.             urlRequest.method = URLRequestMethod.POST;
  70.             urlRequest.data = variables;
  71.            
  72.             //-----[送信]
  73.             var urlLoader:URLLoader = new URLLoader();
  74.             urlLoader.addEventListener(ProgressEvent.PROGRESS, onProress);
  75.             urlLoader.addEventListener(Event.COMPLETE, onComplete);
  76.             urlLoader.load(urlRequest);
  77.         }
  78.        
  79.        
  80.         //------------------------------
  81.         //   読み込み途中
  82.         //------------------------------
  83.         private function onProress(e:ProgressEvent):void
  84.         {
  85.             trace(e.bytesLoaded + " / " + e.bytesTotal);
  86.         }
  87.        
  88.        
  89.         //------------------------------
  90.         //   読み込み完了
  91.         //------------------------------
  92.         private function onComplete(e:Event):void
  93.         {
  94.             e.target.removeEventListener(ProgressEvent.PROGRESS, onProress);
  95.             e.target.removeEventListener(Event.COMPLETE, onComplete);
  96.            
  97.             trace("complete");
  98.         }
  99.     }
  100. }

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

generateZip.php5

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

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

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

2008 年 5 月 15 日

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

Main.as

ACTIONSCRIPT:
  1. package
  2. package
  3. {
  4.     import flash.display.Sprite;
  5.     import flash.net.URLLoader;
  6.     import flash.net.URLLoaderDataFormat;
  7.     import flash.net.URLRequest;
  8.     import flash.net.URLRequestMethod
  9.     import flash.net.URLVariables;
  10.     import flash.events.Event;
  11.     import flash.text.TextField;
  12.    
  13.     public class Main extends Sprite
  14.     {
  15.         private var url:String = "http://***/basicproxy.php";
  16.         private var id:String = "id";
  17.         private var pass:String = "password";
  18.        
  19.         //------------------------------
  20.         //   コンストラクタ
  21.         //------------------------------
  22.         public function Main()
  23.         {
  24.             //-----[送信するデータを格納]
  25.             var variables:URLVariables = new URLVariables();
  26.             variables.id = id;
  27.             variables.pass = pass;
  28.            
  29.             //-----[リクエストの発行]
  30.             var request:URLRequest = new URLRequest();
  31.             request.url = url;
  32.             request.method = URLRequestMethod.POST;
  33.             request.data = variables;
  34.            
  35.             //-----[ローダーの設定]
  36.             var loader:URLLoader = new URLLoader();
  37.             loader.dataFormat = URLLoaderDataFormat.TEXT;
  38.             loader.addEventListener(Event.COMPLETE, onComplete);
  39.             loader.load(request);
  40.         }
  41.        
  42.         //------------------------------
  43.         //   読み込み完了
  44.         //------------------------------
  45.         private function onComplete(e:Event):void
  46.         {
  47.             var loader:URLLoader = e.target as URLLoader;
  48.             loader.removeEventListener(Event.COMPLETE, onComplete);
  49.            
  50.             trace(loader.data);
  51.         }
  52.     }
  53. }

basicproxy.php

PHP:
  1. <?php
  2.     $url = $_POST["url"];
  3.     $id = $_POST["id"];
  4.     $pass  = $_POST["pass"];
  5.    
  6.     $ch = curl_init();
  7.     curl_setopt($ch, CURLOPT_URL, $url);
  8.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  9.     curl_setopt($ch, CURLOPT_USERPWD, "$id:$pass");
  10.     curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  11.     $data= curl_exec($ch);
  12.     curl_close($ch);
  13.    
  14.     echo $data;
  15. ?>

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

「ごはんとFlash」に行ってきた

2008 年 5 月 12 日

dsc_2777

ごはんとFlash」に参加するため鎌倉のbowlsまで行ってきた。すんげー楽しかった。60人くらい集まってたので全員と話すことが出来なくて残念だったけど、立食がまさに正解で動きやすく色んな人と話しやすい雰囲気がありました。ll_koba_llさんも仰ってますが、ドメインやTwitterのアカウント名で覚えているので、自分が配った会社名刺とかはほとんど意味ないなと。名刺に自分のドメインを書かれている方もいて、それで声をかけるきっかけになったりもしました。後半で名刺を切らしてしまってすいませんでした。

社外のクリエーターの方と話が出来たのは本当に貴重で、色んな刺激や情報を頂くことが出来ました。勉強会とは違ったトークメインのイベントは今後も続いて欲しいです。結構みんなこういうのを待っていたんじゃないかと。

途中読み方が分からないブログの初級編でteraさんに弄ってもらいました。ありがとうございます。読み方は5ive(ファイブ)です。

KAYAC道家さんtrick7寺井さんFICC福岡さんを中心としたスタッフの皆様、楽しいイベントをありがとうございました。

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

2008 年 5 月 8 日

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

PHP:
  1. <?php
  2.     echo phpinfo();
  3. ?>

音波形に対応したサウンドボタン

2008 年 4 月 28 日

※soundボタンをクリックすると音が鳴るので注意。
サウンドスペクトラムを使って、音にシンクロしたサウンドボタン用のクラスを作ってみた。最初にsetPixel()でピクセルを描画しておいて、スペクトラム波形に合わせてscaleYを変化させてます。下記がそのクラスファイル。

SoundSpectrum.as

ACTIONSCRIPT:
  1. package info.five.ui
  2. {
  3.     import flash.display.Sprite;
  4.     import flash.display.Bitmap;
  5.     import flash.display.BitmapData;
  6.     import flash.events.Event;
  7.     import flash.media.SoundMixer;
  8.     import flash.utils.ByteArray;
  9.    
  10.     public class SoundSpectrum extends Sprite
  11.     {
  12.         private var lineNum:uint;
  13.         private var lineHeight:uint;
  14.         private var lineInterval:uint;
  15.         private var bmAry:Array = [];
  16.        
  17.         //------------------------------
  18.         //   コンストラクタ
  19.         //------------------------------
  20.         public function SoundSpectrum(targetNum:uint = 5, targetHeight:uint = 20, targetInterval:uint = 1, targetColor:uint = 0x000000)
  21.         {
  22.             lineNum = targetNum;
  23.             lineHeight = targetHeight;
  24.             lineInterval = targetInterval;
  25.            
  26.             this.addEventListener(Event.ENTER_FRAME, onRender);
  27.            
  28.             //-----[ピクセルの描画]
  29.             var bmd:BitmapData;
  30.             var bm:Bitmap;
  31.            
  32.             for (var i = 0; i <lineNum; i++)
  33.             {
  34.                 bmd = new BitmapData(1, 100);
  35.                 bm = new Bitmap(bmd);
  36.                 this.addChild(bm);
  37.                 bm.x = i * (lineInterval + 1);
  38.                
  39.                 bmd.setPixel(0, 0, targetColor);
  40.                 bmAry.push(bm);
  41.             }
  42.             bmd.dispose();
  43.         }
  44.        
  45.        
  46.         //------------------------------
  47.         //   レンダー
  48.         //------------------------------
  49.         private function onRender(e:Event):void
  50.         {
  51.             var count:uint = 256 / lineNum;
  52.             var value:Number;
  53.             var ba:ByteArray = new ByteArray();
  54.            
  55.             SoundMixer.computeSpectrum(ba, false, 0);
  56.            
  57.             for (var i:uint = 0; i <256; i++)
  58.             {
  59.                 value = -ba.readFloat() * lineHeight - 1;
  60.                
  61.                 for (var j:uint = 0; j <lineNum; j++)
  62.                 {
  63.                     if (i == Math.floor(count * j)) bmAry[j].scaleY = value;
  64.                 }
  65.             }
  66.         }
  67.     }
  68. }

続いてドキュメントクラスには以下のように記述します。引数はSoundSpectrum(ラインを何本にするか, ラインの最大高さ, ラインの間隔, ラインの色)となります。インスタンス化した後にx,yプロパティを与えてaddChild()でステージに配置。デフォルトで数値を持たしているので、カスタマイズしたくない場合は引数なしでも大丈夫です。

ACTIONSCRIPT:
  1. var sp:SoundSpectrum = new SoundSpectrum(8, 30, 1, 0x000000);
  2. soundBtn.addChild(sp);
  3. sp.x = 32;
  4. sp.y = 10;

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

2008 年 4 月 23 日

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

Main.as

ACTIONSCRIPT:
  1. package
  2. {
  3.     import flash.display.Stage;
  4.     import flash.display.Sprite;
  5.     import flash.net.URLVariables;
  6.     import flash.net.URLRequest;
  7.     import flash.net.URLRequestMethod;
  8.     import flash.net.navigateToURL;
  9.    
  10.    
  11.     public class Main extends Sprite
  12.     {
  13.         //------------------------------
  14.         //   コンストラクタ
  15.         //------------------------------
  16.         public function Main()
  17.         {
  18.             sendData();
  19.         }
  20.        
  21.         //------------------------------
  22.         //   データ送信
  23.         //------------------------------
  24.         public function sendData():void
  25.         {
  26.             var variables:URLVariables = new URLVariables();
  27.             variables.title = "5ive.blog";
  28.             variables.url = "http://www.5ive.info/blog/";
  29.             variables.text = "PHPに複数のデータを渡す方法";
  30.            
  31.             var urlRequest:URLRequest = new URLRequest();
  32.             urlRequest.url = "variables.php";
  33.             urlRequest.method = URLRequestMethod.POST;
  34.             urlRequest.data = variables;
  35.            
  36.             //phpに送信
  37.             navigateToURL(urlRequest , "_self");
  38.         }
  39.     }
  40. }

variables.php

PHP:
  1. <?php
  2.     $title = $_POST['title'];
  3.     $url = $_POST['url'];
  4.     $text = $_POST['text'];
  5.    
  6.     echo "title = ".$title."<br />";
  7.     echo "url = ".$url."<br />";
  8.     echo "text = ".$text."<br />";
  9. ?>

ICC オープンスペースに行ってきた

2008 年 4 月 21 日

dsc_2220

前エントリーMake:Tokyo Meetingの後にはしごでICCに行きました。行く途中に3人で歩きながらの雑談。ワンセグを視聴すると字幕がついててびっくりとか、モバイル系の話とか、Felicaの非接触端末の話とか、FlashDevelopβ7出たねとか、iPotchで自作アプリ開発して遊んでるとか、いろいろ。

計算の庭
RFIDタグが仕込まれたカードを持って、計算しながらゲートをくぐって73になるようにゴールを目指す。非接触端末でのデータのやり取りはこれからおもしろくなりそう。

多義の森
Processingみたいなプログラミングモーション。これすごすぎ!1ピクセルの点が気持ちよく動いてて、ずーっと見ていられる。スクリーンセーバーとかにしたら絶対かっこいい。欲しい。

TENORI-ON
実機を初めて触った。思った以上に操作難しいかも。説明書見ないとルールが良く分かりません。

マイクロ・プレゼンス
地味に一番すごいと思ったかも。小さい昆虫をひたすらズームして見れるもの。すべての部位にピントをあわせるという新しい写真の技法を開発してるらしい。この画像処理のアルゴリズム知りたい。Flashでできないかな。

ICCには初めて行ったんだけど、結構見ごたえがあって面白かった。メディアアートとかインスタレーション好きにはお勧めですよ。ゲンさん、遠藤さん、お疲れ様でした。

Make:Tokyo Meetingに行ってきた

2008 年 4 月 21 日

dsc_2206

dsc_2211

dsc_2217

dsc_2219

日曜日にMake:Tokyo Meetingに参加してきました。現地でゲンさんと合流。そして会場ではイメージソースの遠藤さんに偶然遭遇。三人で一緒に見て回ることに。グランドでは真空砲ぶっぱなしてキャベツ爆破とか、セグウェイに乗り回せたり。体育館では電子工作の作品展示や、GAINERワークショップとか基盤販売とか割とカオスな事になってました。工学部理系男子(眼鏡)が会場の9割を占めてて、Web系とはまた違った世界でした。あまりFlashな人たちはいなかったと思われ。

気になった作品はリアルのサウンドスペクトラムを可視化してたやつと、ウダーというオリジナル電子楽器(ミニ冷蔵庫がスピーカーになってて、コントローラーがかっこいい)で演奏してたやつ。全体的にマニアック過ぎたけどこれはこれでおもしろかったなぁと。その後3人でICCに向かいました。続きは次エントリーで。

あと、写真勝手に載せちゃいました。すいません。問題があれば連絡ください。

mouseChildrenとmouseEnabledについて

2008 年 4 月 18 日

今更ながら知ったのでメモ。AS2でいうenabled = falseをしたくて調べたら、AS3ではもっと使い勝手が良くなっているようだ。

mouseEnabled
これはマウスイベントを受け取るかどうかを判断するプロパティ。こいつをfalseにするとマウスイベントを受け取らなくなるので、一時的にリスナーを切りたいけどremoveEventListenerするのが面倒とか、あるタイミングだけマウスに反応させたくない時に使用する。

mouseChildren
これと合わせて覚えておきたいのがmouseChildrenだ。mouseChildrenはオブジェクトの子に対してマウスが有効かどうかを判断するプロパティ。つまり親MCにぶらさがる子MCすべてのマウスイベントの伝播を止めることができる。一括してマウスイベントを受け取りたくない時に使うとかなりの手間が省ける。

ACTIONSCRIPT:
  1. mc.mouseChildren = false;
  2. mc.mouseEnabled = false;

こうするとmc以下のオブジェクトにマウスイベントが伝わらなくなるので便利ですよと。