作成日

17 November 2009

はじめに

Adobe AIR 2.0 の新機能であるマルチタッチ機能を活用したアプリケーション Touch Viewer は、指定ディレクトリまたは、マウントした USB ストレージデバイス直下に保存されている画像ファイル JPG、GIF、PNG 形式 を一覧表示して、選択した画像を閲覧することのできる Flex 4 ベースの画像ビューアアプリケーションです。

この記事では、Touch Viewer で使用している Adobe AIR 2.0 の API について、具体的に説明していきたいと思います。

ダウンロード

重要: このサンプルアプリケーションは、AIR 2 betaの機能を体験するために作成されています。お試しになる場合は、AIR 2 beta ランタイムを先にインストールする必要があります。なお、既にAIR 1.xのランタイムがOSにインストールされている場合は、上書きされてしまいますのでご注意ください。元に戻す場合は、AIR 2 beta ランタイムをアンインストールし、AIR 1.5.2 ランタイムをインストールします。詳細はリリースノート(英語) をご覧ください。

開発環境

  • Adobe Flash Builder 4 beta 2
  • Adobe AIR 2.0 beta
  • HP TouchSmart tx2
    ( マルチタッチスクリーン検証機 )
  • Apple MacBook + Magic Mouse
    ( MacBook はマルチタッチトラックパッドが採用されているモデル )

Touch Viewer の主な機能

Touch Viewer では Adobe AIR 2.0 の新機能を活用して、以下の機能を実現しています。

  • マウスジェスチャーによる画像のサイズ、角度、明度のコントロール
    ( 要・Windows 7、Mac OS 10.6 以上でマルチタッチをサポートしている PC 環境 )
  • USB ストレージデバイスのマウント、アンマウント検知
    ( マウント時に、ドライブ直下の画像一覧を表示 )
  • 画像ファイル・タイプごとに関連するアプリケーションの起動
    ( Mac 版のみ対応。Windows 環境では「 Windows 画像と FAX ビューア」を起動 )
  • ネイティブインストーラ

マウスジェスチャーのマルチタッチイベントを取得する

Touch Viewer では、画像のリサイズ、回転、明度の変更処理を、TransformGestureEvent を取得してコントロールしています。Flex 4 で作成する ( Flash ベースの ) Adobe AIR 2.0 アプリケーションでマウスジェスチャーなどのマルチタッチイベントを取得するためには、Multitouch.inputMode プロパティの値を "gesture" (MultitouchInputMode.GESTURE) にする必要があります。この定数を定義しない限り、TransformGestureEvent は発行されません。そして MultitouchInputMode クラスには、他にも TOUCH_POINT という、マルチタッチ入力モードの定数が用意されていますが、GESTURE と併用することはできません。

例 : Multitouch.inputMode をマウスジェスチャーに定義

Multitouch.inputMode = MultitouchInputMode.GESTURE

TransformGestureEvent には、複数のイベントタイプが存在しますが、今回 Touch Viewer で使用しているイベントタイプは、以下の 4 つです。OS や ハードウェアの環境によって、取得できるイベントの種類や挙動がそれぞれ異なるので、テストや検証作業を慎重に行う必要があります。

  • TransformGestureEvent.GESTURE_PAN
  • TransformGestureEvent.GESTURE_ZOOM
    ( 筆者の環境では、Windows 環境でのみ取得できました )
  • TransformGestureEvent.GESTURE_ROTATE
    ( 筆者の環境では、Windows 環境でのみ取得できました )
  • TransformGestureEvent.GESTURE_SWIPE
    ( 筆者の環境では、Mac + Magic Mouse 環境でのみ取得できました )

取得したマルチタッチイベントの取り扱い

取得した TransformGestureEvent インスタンスには、さまざまなプロパティが含まれています。今回 Touch Viewer で使用している TransformGestureEvent の主なプロパティは、以下の通りです。

  • scaleX(scaleY)
    ( Windows 環境でサイズ変更処理に使用 )
  • rotation
    ( Windows 環境で角度変更処理に使用 )
  • offsetX
    ( Mac 環境でサイズ変更処理に使用 )
  • offsetY
    ( Mac 環境で角度変更処理に使用 )
  • localX(localY)
    ( 明度変更処理に使用 )
  • phase
    ( 明度変更処理に使用 )

これらプロパティの値の変化を、以下のコードのように、表示画像の scaleX(scaleY)、rotation、colorTransform プロパティに適応させます。

例 : TransformGestureEvent.GESTURE_ZOOM を利用した画像のサイズ変更処理

var _scale:Number = 1; addEventListener(TransformGestureEvent.GESTURE_ZOOM, gestureZoomHandler); function gestureZoomHandler(event:TransformGestureEvent):void { var minScale_:Number = 0.3; var maxScale_:Number = 2; _scale *= event.scaleX; if(_scale < minScale_ ) { _scale = minScale_; } else if(_scale > maxScale_ ) { _scale = maxScale_; } target.scaleX = target.scaleY = _scale; }

例 : TransformGestureEvent.GESTURE_ROTATE を利用した画像の角度変更処理

var _rotate:Number = 0; addEventListener(TransformGestureEvent.GESTURE_ROTATE, gestureRotateHandler); function gestureRotateHandler(event:TransformGestureEvent):void { _rotate += event.rotation; target.rotation = _rotate; }

例 : TransformGestureEvent.GESTURE_PAN を利用した画像の明度変更処理

var _panDX:Number; var _lightness:Number = 0; addEventListener(TransformGestureEvent.GESTURE_PAN, gesturePanHandler); function gesturePanHandler(event:TransformGestureEvent):void { switch (event.phase) { case GesturePhase.BEGIN : _panDX = event.localX; break; case GesturePhase.UPDATE : _lightness += (event.localX - _panDX) / 100; updateLightness(); break; } } function updateLightness():void { var d:Number; var colorTransform:ColorTransform = new ColorTransform(); if(_lightness < 0) { d = 1 + _lightness; colorTransform.redMultiplier = d; colorTransform.greenMultiplier = d; colorTransform.blueMultiplier = d; } else { d = 1 - _lightness; colorTransform.redMultiplier = d; colorTransform.greenMultiplier = d; colorTransform.blueMultiplier = d; colorTransform.redOffset = _lightness * 255; colorTransform.greenOffset = _lightness * 255; colorTransform.blueOffset = _lightness * 255; } target.transform.colorTransform = colorTransform; }

USB ストレージデバイスのマウント、アンマウント検知

USB ストレージデバイスのマウント、アンマウントを検知するためには、StorageVolumeInfo インスタンスに対して、StorageVolumeChangeEvent のリスナーイベントハンドラを定義します。
用意されているイベントタイプは、以下の2つです。

  • StorageVolumeChangeEvent.STORAGE_VOLUME_MOUNT
  • StorageVolumeChangeEvent.STORAGE_VOLUME_UNMOUNT

イベントハンドラの引数である StorageVolumeChangeEvent インスタンスの rootDirectory プロパティには、割り振られたドライブのパスが含まれているので、USB ストレージデバイスのマウントのタイミングに合わせて、簡単にドライブを閲覧、操作することができます。

例 : StorageVolumeChangeEvent のリスナーイベントハンドラを定義

var svi:StorageVolumeInfo; svi = StorageVolumeInfo.storageVolumeInfo; svi.addEventListener(StorageVolumeChangeEvent.STORAGE_VOLUME_MOUNT, storageVolumeMountHandler, false, 0, true); svi.addEventListener(StorageVolumeChangeEvent.STORAGE_VOLUME_UNMOUNT, storageVolumeUnmountHandler, false, 0, true); function storageVolumeMountHandler(event:StorageVolumeChangeEvent):void { var imageDirectory:File = event.rootDirectory; //TODO:任意の処理 } function storageVolumeUnmountHandler(event:StorageVolumeChangeEvent):void { //TODO:任意の処理 }

最後に

今回 Touch Viewer を作る過程で、Adobe AIR 2.0 の API について調べて、検証機として用意した PC の仕様を確認したり、サンプルプロジェクトをいくつか作成したりしましたが、OS やハードウェアの互換性を保つことが難しいことを実感しました。

Adobe AIR には、さまざまな環境でマルチタッチ機能を実現するための手段が用意されていますが、最終的にはハードウェアの性能に大きく左右される技術なので、今後どのように一般に普及させるかが課題になるのではないかと思います。