タグ : cameraRoll

手書きメモアプリを作る。

手書きしたBitmapDataをカメラロールに保存するシンプルなメモアプリケーションです。

今回、Kevin HoytさんのAndroid UI 風コンポーネントを利用して作ってみました。

http://www.appforandroid.info/app/memo.apk

Kevinさんのコンポーネントを利用する際の注意点として、
http://www.himco.jp/articles/pdf/kevinHoytComponents.pdf
に記載されている注意点の他に、固定解像度(縦向き)での利用に制限されています。
よってマルチ解像度で利用する際にはコンポーネントの位置や大きさを自分で調整してあげる必要があります。

以下ソースになります。

package  
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.CameraRoll;
	import flash.events.MouseEvent;
	import flash.utils.Timer;
	import Menu;
	import MenuEvent;

	public class Main extends MovieClip
	{
		var canvs:Bitmap = new Bitmap();
		var pointer:Point = new Point();
		var timer:Timer;
		
		public function Main() 
		{
			
			var sp:Sprite = new Sprite();
			canvs.bitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xFFFFFF);
			sp.addChild(canvs);
			addChild(sp);
			
			timer = new Timer(10);
			timer.addEventListener(TimerEvent.TIMER, onDrawingHandler);
			
			sp.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent) {
				pointer.x = canvs.mouseX;
				pointer.y = canvs.mouseY;
				timer.start();
			});
			sp.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent) {
				timer.stop();
			});
			
			//メニューの生成
			
			var menu:Menu = new Menu( new Array( 
				{ path:"file.png", label:"RESET" }, 
				{ path:"save.png", label:"SAVE" } 
			) );
			menu.addEventListener(MenuEvent.CLICK, onMenuClickHandler);
			addChild(menu);
	
		}
		
		//メニューのボタンがクリックされたときのアクション
		private function onMenuClickHandler(e:MenuEvent):void 
		{
			switch(e.label) {
				case "RESET":
					resetCanvas();
				break;
				case "SAVE":
					imgSave();
				break;
				default:
				break;
			}
		}
		
		//bitmapdataに線を描く
		private function onDrawingHandler(e:TimerEvent):void 
		{
			var temp:Sprite = new Sprite();
			temp.graphics.lineStyle(4, 0x000000);
			temp.graphics.moveTo(pointer.x, pointer.y);
			temp.graphics.lineTo(canvs.mouseX, canvs.mouseY);
			var bmpd:BitmapData = canvs.bitmapData;
			bmpd.draw(temp);
			
			pointer.x = canvs.mouseX;
			pointer.y = canvs.mouseY;
		}
		//キャンバスを白く塗り直す。
		private function resetCanvas():void {
			var bmpd:BitmapData = canvs.bitmapData;
			bmpd.fillRect(
				new Rectangle(0, 0, bmpd.width, bmpd.height),
				0xFFFFFF
			);
		}
		//画像をカメラロールに保存する
		public function imgSave():void {
			var cmrl:CameraRoll = new CameraRoll();
			if (CameraRoll.supportsAddBitmapData) {
				cmrl.addBitmapData(canvs.bitmapData);
			}
		}
	}
}

CameraRollについて

CameraRollを利用すると主に以下の2つのアクションが可能です。

カメラロールに bitmapDataを保存する。

var bmp:BitmapData = new BitmapData(10, 10, false, 0xFFFFFFFF);
var cr:CameraRoll = new CameraRoll();
cr.addBitmapData(bmp);

カメラロールを参照する。

カメラロールを参照する場合は少し複雑になり、CameraUIと同じような挙動をします。

CameraRoll.browseForImage()を叩くと、デバイスの画像ビューワーが呼び出され特定の画像1枚を選ぶような遷移になります。ここで1枚を選ぶと画像ビューワは閉じられairforandroidに戻ります。戻った際にイベントからMediaPromiseに選択した画像の情報が渡されます。

adobeの公式ヘルプにまんまお手本が乗っているので↓に引用部分を転載します。

package
{
	import flash.media.CameraRoll;
	import flash.media.MediaPromise;
	import flash.media.MediaType;
	import flash.events.MediaEvent;
	import flash.events.Event;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.IOErrorEvent;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;

	public class Main extends Sprite{
		private var mediaSource:CameraRoll = new CameraRoll();

		public function Main() {
			this.stage.align = StageAlign.TOP_LEFT;
			this.stage.scaleMode = StageScaleMode.NO_SCALE;

			if( CameraRoll.supportsBrowseForImage )
			{
				log( "Browsing for image..." );
				mediaSource.addEventListener( MediaEvent.SELECT, imageSelected );
				mediaSource.addEventListener( Event.CANCEL, browseCanceled );

				mediaSource.browseForImage();
			}
			else
			{
				log( "Browsing in camera roll is not supported.");
			}
		}

		private var imageLoader:Loader;
		private function imageSelected( event:MediaEvent ):void
		{
			log( "Image selected..." );

			var imagePromise:MediaPromise = event.data;

			imageLoader = new Loader();
			if( imagePromise.isAsync )
			{
				log( "Asynchronous media promise." );
				imageLoader.contentLoaderInfo.addEventListener( Event.COMPLETE, imageLoaded );
				imageLoader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, imageLoadFailed );
				imageLoader.loadFilePromise( imagePromise );
			}
			else
			{
				//log( "Synchronous media promise." );
				imageLoader.loadFilePromise( imagePromise );
				this.addChild( imageLoader );
			}
		}

		private function browseCanceled( event:Event ):void
		{
			log( "Image browse canceled." );
		}

		private function imageLoaded( event:Event ):void
		{
			log( "Image loaded asynchronously." );
			this.addChild( imageLoader );
		}

		private function imageLoadFailed( event:Event ):void
		{
			log( "Image load failed." );
		}

		private function log( text:String ):void
		{
			//trace( text );
		}
	}
}