
シニアテクニカルライター
Adobe
図 1 の PhotoUpload サンプルアプリケーションは、次のような Adobe AIR のファイル操作機能を示します。

図 1. JPEG ファイルのアップロードが可能なサンプルアプリケーション
注意:このサンプルアプリケーションは、説明のためにそのままの状態で提供されています。
この記事に書かれた操作を行うには、次のソフトウェアとファイルが必要です。
このサンプルアプリケーションには、次のファイルが含まれています。
このアプリケーションを使用するには、Web カメラがインストールされている必要があります。また、PHP 対応の Web サーバへのアクセス権も必要です。
HTML ベースのアプリケーション構築の経験があることが推奨されます。このクイックスタートの開始方法について詳しくは、「Building the Quick Start sample applications with HTML」を参照してください。
このサンプルアプリケーションでは、Web カメラから画像をキャプチャし、その画像(JPEG ファイルとして保存される)を Web サーバにアップロードできます。
フォトアップローダでは、SWF ファイルの JPGEncoder クラスを使用してデータが JPEG 形式に変換されます。JPGEncoder クラスは、ActionScript 3.0 Corelib プロジェクト(http://code.google.com/p/as3corelib)でパブリッシュされます。
アプリケーション(PhotoUploadHTML.air)を実行する前に、index.php ファイル(PHP ディレクトリのソースファイルに付属している)を PHP 対応の Web サーバの http://localhost/PhotoSyncUpload/ フォルダにインストールします。また、Web カメラがコンピュータにインストールされていることを確認します。
アプリケーションをテストするには:
AIR クラスの使用方法について詳しくは、「Adobe AIR Language Reference for HTML Developers」を参照してください。
Uploader.js ファイル内の appInit() メソッドは、ActionScript 3.0 ドキュメントの Camera クラスと Video クラスセクションに記載されている 2 つのクラスを使用しています。カメラオブジェクト(Camera クラスのインスタンス)をユーザのコンピュータの Web カメラに割り当てるために、Camera クラスの getCamera() メソッドが呼び出されます。カメラがない場合は、ユーザに通知するために alert() 関数が呼び出されます。ビデオオブジェクト(Video クラスのインスタンス)は、カメラでキャプチャした画像を表示するために割り当てられた ActionScript 3.0 表示オブジェクトです。
camera = window.runtime.flash.media.Camera.getCamera();
if (camera)
{
video = new window.runtime.flash.media.Video();
video.attachCamera(camera);
camera.addEventListener(air.ActivityEvent.ACTIVITY, setSize);
}
else
{
alert("No cameras are available.");
}
setSize() 関数では、ビデオの高さと幅が設定され、次に shoot() 関数が呼び出されます。
function setSize()
{
video.width = camera.width * 2;
video.height = camera.height * 2;
shoot(false);
}
shoot() 関数では、不透明な白い NativeWindow を短時間画面いっぱいに表示してカメラのフラッシュをシミュレートする flasher() 関数が呼び出されます。
function shoot(flash)
{
if (flash)
{
flasher();
}
bmd = new window.runtime.flash.display.BitmapData(video.width, video.height);
bmd.draw(video);
saveTemp();
}
function flasher()
{
var windowInitOpts = new air.NativeWindowInitOptions();
windowInitOpts.systemChrome = air.NativeWindowSystemChrome.NONE;
windowInitOpts.type = air.NativeWindowType.LIGHTWEIGHT;
var flashCube = new air.NativeWindow(windowInitOpts);
flashCube.x = 0;
flashCube.y = 0;
flashCube.width = air.Capabilities.screenResolutionX;
flashCube.height = air.Capabilities.screenResolutionY;
flashCube.visible = true;
setTimeout(closeFlash, 100, flashCube);
}
function closeFlash(flashCube) {
flashCube.close();
}
appInit() メソッドでの初期化中にアプリケーションから初めて shoot メソッドを呼び出す場合、このメソッドの flash パラメータには false が設定されます。
次に、shoot() メソッドでビデオオブジェクトに画像がキャプチャされ、BitmapData オブジェクト bmd に保存されます。flash.display.BitmapData クラスについては、ActionScript 3.0 のドキュメントを参照してください。
bmd = new window.runtime.flash.display.BitmapData(video.width, video.height); bmd.draw(video);
アプリケーションの初期化時および「Preview」ボタンのクリック時には、saveTemp() メソッドで画像が JPEG ファイルに保存されます。その後は、このファイルが img 画像に読み込まれます。
bmd オブジェクトに格納されている BitmapData データは、JPEG 形式に変換する必要があります。この変換は、corelib プロジェクト(http://code.google.com/p/as3corelib)でパブリッシュされた JPGEncoder ActionScript 3.0 クラスで行われます。swf ディレクトリ内のソースファイルで提供される JPGEncoderLib.swf ファイルには、該当する JPGEncoder クラスが含まれています。また、この HTML ベースのアプリケーションでは、次のスクリプトタグ(index.html ファイル内)を使用して SWF ファイルを読み込むことによって、その SWF ファイル内のクラスが JavaScript コードで使用可能になります。
<script src="swf/JPGEncoderLib.swf" type="application/x-shockwave-flash"></script>
saveTemp() 関数を使用すると、JPEG データが一時ファイルに保存されます。この一時ファイルは、air.File.createTempFile() を呼び出すことによって作成されます。データをファイルに保存するために、FileStream オブジェクトが作成され、そのオブジェクトの writeBytes() メソッドが呼び出されます。次に、一時ファイルがドキュメント内の img 画像に読み込まれます。JPGEncoder オブジェクトの encode() メソッドを呼び出すことにより、画像データを JPEG エンコード形式のデータが格納される ByteArray に変換しています。
function saveTemp()
{
tempFile = air.File.createTempFile();
temps.push(tempFile);
saveJPEG(tempFile);
img.src = "";
img = window.document.getElementById("img");
img.src = tempFile.url;
img.width = 320;
img.height = 240;
}
function saveJPEG(file) {
stream = new air.FileStream();
stream.open(file, air.FileMode.WRITE);
var data = getJPEGData(bmd);
stream.writeBytes(data, 0, data.length);
stream.close();
return file;
}
function getJPEGData(bmd) {
var jpegEncoder = new window.runtime.com.adobe.images.JPGEncoder();
return jpegEncoder.encode(bmd);
}
ユーザが「保存」ボタンをクリックすると、画像は、save() メソッドによってアプリケーションリソースディレクトリの images サブディレクトリに JPEG ファイルとして保存されます。ファイルの名前は、Date オブジェクトの time プロパティで設定されるタイムスタンプに基づきます。
function save()
{
var timestamp = new Date().getTime().toString();
var path = "images/" + timestamp + ".jpg";
file = air.File.applicationStorageDirectory.resolvePath(path);
saveJPEG(file);
}
Uploader.as ファイルには、ファイルを Web サーバにアップロードするコードが含まれています。保存したファイルのリストは、files 配列(File オブジェクトの配列)に格納されます。upload() メソッドでは、アプリケーションストレージディレクトリの images サブディレクトリでファイルのリストの検索が行われます。
function upload()
{
totalSize = 0;
files = new Array();
var dir = air.File.applicationStorageDirectory.resolvePath("images");
var allNodes = dir.getDirectoryListing();
for (var i = 0; i < allNodes.length; i++)
{
file = allNodes[i];
if (!file.isDirectory)
{
files.push(file);
totalSize += file.size;
}
}
url = UPLOAD_URL
uploadedSoFar = 0;
uploadNext();
}
uploadNext() 関数では files 配列から 1 つの File オブジェクトが抽出され、ファイルをアップロードする uploadFile() 関数が呼び出されます。
function uploadNext()
{
if (files.length > 0)
{
currentFile = files.pop();
uploadFile(currentFile);
}
}
function uploadFile(file)
{
var urlRequest = new air.URLRequest(url);
urlRequest.method = air.URLRequestMethod.POST;
file.addEventListener(air.ProgressEvent.PROGRESS, uploadProgress);
file.addEventListener(air.Event.COMPLETE, uploadComplete);
file.addEventListener(air.SecurityErrorEvent.SECURITY_ERROR, uploadError);
file.addEventListener(air.HTTPStatusEvent.HTTP_STATUS, uploadError);
file.addEventListener(air.IOErrorEvent.IO_ERROR, uploadError);
file.upload(urlRequest, "uploadfile");
}
ploadFile() 関数では アップロード対象の File オブジェクトの様々なイベントリスナーが設定されます。
function uploadProgress(event)
{
var uploadedAmt = uploadedSoFar + event.bytesLoaded;
event.bytesLoaded = uploadedAmt;
event.bytesTotal = totalSize;
air.trace("Progress", event.bytesLoaded, event.bytesTotal);
}
function uploadComplete(event)
{
uploadedSoFar += currentFile.size;
var newLocation = currentFile.parent.resolvePath("uploaded/" + currentFile.name);
uploadNext();
}
function uploadError(event)
{
var errorStr = event.toString();
air.trace("Error uploading: " + currentFile.nativePath + "\n Message: " + errorStr);
}
uploadComplete() 関数(ファイルのアップロード時に呼び出されるイベントハンドラ)では、uploadNext() 関数が呼び出され、次のファイル(存在する場合)がアップロードされます。
Web サーバに掲載した PHP ページでは、POST データとして提供されるファイルを、アップロード対象(Web サーバの「uploaded」サブディレクトリに保存)のファイルの形で受け入れるキューとして文字列が認識されます。
appInit() 関数では、終了イベントのイベントリスナーが設定されます。このリスナーは、アプリケーションの終了時に NativeApplication オブジェクトによって送出されます。
air.NativeApplication.nativeApplication.addEventListener(air.Event.EXITING, appExiting);
NativeApplication オブジェクトでは、ユーザが main を閉じるときに終了イベントが送出されます。終了イベントは appExiting() 関数で処理され、アプリケーションが実際に終了する前に、セッション中に使用した一時ファイルの配列が保存されます。
function appExiting(event)
{
for (i = 0; i < temps.length; i++)
{
tempFile = temps[i];
tempFile.deleteFile();
}
}
Jeff Swartzは、1992年にMacromedia(現Adobe Systems)に入社し、現在はAdobe AIR担当のテクニカルライターを務めています。Jeffは、University of Illinois at Urbana-Champaignのコンピュータサイエンス学学士号と、Edinburgh University人工知能学部での就学経験を有しています。サンフランシスコベイエリアのファンは、Jeffのトロンボーン演奏を寛大に許容しています。また、Vienna Beef Ltd.のダンシングホットドッグ、Big Frankとして活躍した経験もあります。