make AS Camera actually take a picture.  Needs better UI at some point

Project: http://git-wip-us.apache.org/repos/asf/flex-asjs/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-asjs/commit/b83027c6
Tree: http://git-wip-us.apache.org/repos/asf/flex-asjs/tree/b83027c6
Diff: http://git-wip-us.apache.org/repos/asf/flex-asjs/diff/b83027c6

Branch: refs/heads/develop
Commit: b83027c65bbf7387792d29e63fb580602d783fe7
Parents: 135f04d
Author: Alex Harui <aha...@apache.org>
Authored: Tue May 6 00:12:22 2014 -0700
Committer: Alex Harui <aha...@apache.org>
Committed: Tue May 6 00:12:22 2014 -0700

----------------------------------------------------------------------
 frameworks/as/projects/FlexJSUI/build.xml       |   2 +-
 .../as/projects/FlexJSUI/compile-config.xml     |   2 +-
 .../src/org/apache/cordova/camera/Camera.as     |  95 +++++-
 .../src/org/apache/flex/utils/PNGEncoder.as     | 304 +++++++++++++++++++
 .../flex/utils/ViewSourceContextMenuOption.as   |   2 +-
 5 files changed, 395 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/b83027c6/frameworks/as/projects/FlexJSUI/build.xml
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/FlexJSUI/build.xml 
b/frameworks/as/projects/FlexJSUI/build.xml
index 514b42d..3dfe5d8 100644
--- a/frameworks/as/projects/FlexJSUI/build.xml
+++ b/frameworks/as/projects/FlexJSUI/build.xml
@@ -72,7 +72,7 @@
             <jvmarg line="${compc.jvm.args}"/>
             <load-config filename="compile-config.xml" />
             <arg value="+playerglobal.version=${playerglobal.version}" />
-            <arg value="+env.PLAYERGLOBAL_HOME=${env.PLAYERGLOBAL_HOME}" />
+            <arg value="+env.AIR_HOME=${env.AIR_HOME}" />
         </compc>
     </target>
 

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/b83027c6/frameworks/as/projects/FlexJSUI/compile-config.xml
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/FlexJSUI/compile-config.xml 
b/frameworks/as/projects/FlexJSUI/compile-config.xml
index a72ad58..7db518e 100644
--- a/frameworks/as/projects/FlexJSUI/compile-config.xml
+++ b/frameworks/as/projects/FlexJSUI/compile-config.xml
@@ -22,7 +22,7 @@
         <accessible>false</accessible>
         
         <external-library-path>
-            
<path-element>${env.PLAYERGLOBAL_HOME}/${playerglobal.version}/playerglobal.swc</path-element>
+            
<path-element>${env.AIR_HOME}/frameworks/libs/air/airglobal.swc</path-element>
         </external-library-path>
         
         <locale/>

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/b83027c6/frameworks/as/projects/FlexJSUI/src/org/apache/cordova/camera/Camera.as
----------------------------------------------------------------------
diff --git 
a/frameworks/as/projects/FlexJSUI/src/org/apache/cordova/camera/Camera.as 
b/frameworks/as/projects/FlexJSUI/src/org/apache/cordova/camera/Camera.as
index 9a8a980..3984b44 100644
--- a/frameworks/as/projects/FlexJSUI/src/org/apache/cordova/camera/Camera.as
+++ b/frameworks/as/projects/FlexJSUI/src/org/apache/cordova/camera/Camera.as
@@ -18,6 +18,25 @@
 
////////////////////////////////////////////////////////////////////////////////
 package org.apache.cordova.camera
 {
+       import flash.display.BitmapData;
+       import flash.display.DisplayObject;
+       import flash.display.DisplayObjectContainer;
+       import flash.display.Sprite;
+       import flash.events.ActivityEvent;
+       import flash.events.KeyboardEvent;
+       import flash.events.MouseEvent;
+       import flash.filesystem.File;
+       import flash.filesystem.FileMode;
+       import flash.filesystem.FileStream;
+       import flash.geom.Rectangle;
+       import flash.media.Camera;
+       import flash.media.Video;
+       import flash.ui.Keyboard;
+       import flash.utils.ByteArray;
+       
+       import org.apache.flex.utils.PNGEncoder;
+
+       [Mixin]
        public class Camera
        {
                public static var DestinationType:Object = {
@@ -48,13 +67,20 @@ package org.apache.cordova.camera
                        FRONT : 1      // Use the front-facing camera
                };
 
+               private static var root:DisplayObjectContainer;
+               
+               public static function init(r:DisplayObjectContainer):void
+               {
+                       root = r;               
+               }
+               
                public function Camera()
                {
-                       pictureSourceType = 
Camera.PictureSourceType.PHOTOLIBRARY;
-                       destinationType = Camera.DestinationType.DATA_URL;
-                       mediaType = Camera.MediaType.PICTURE;
-                       encodingType = Camera.EncodingType.JPEG;
-                       direction = Camera.Direction.BACK;
+                       pictureSourceType = 
org.apache.cordova.camera.Camera.PictureSourceType.PHOTOLIBRARY;
+                       destinationType = 
org.apache.cordova.camera.Camera.DestinationType.DATA_URL;
+                       mediaType = 
org.apache.cordova.camera.Camera.MediaType.PICTURE;
+                       encodingType = 
org.apache.cordova.camera.Camera.EncodingType.JPEG;
+                       direction = 
org.apache.cordova.camera.Camera.Direction.BACK;
                }
                
                public var pictureSourceType:int;
@@ -63,14 +89,69 @@ package org.apache.cordova.camera
                public var encodingType:int;
                public var direction:int;
                
+               private var cameraSuccess:Function;
+               private var cameraError:Function;
+               private var ui:Sprite;
+               private var camera:flash.media.Camera;
+               
                public function getPicture( cameraSuccess:Function, 
cameraError:Function, cameraOptions:Object ) : void
                {
-                       // stub for JavaScript version
+                       this.cameraSuccess = cameraSuccess;
+                       this.cameraError = cameraError;
+                       
+                       camera = flash.media.Camera.getCamera();
+                       
+                       if (camera != null) {
+                               ui = new Sprite();
+                               var video:Video = new Video(camera.width * 2, 
camera.height * 2);
+                               video.attachCamera(camera);
+                               ui.addChild(video);
+                               root.addChild(ui);
+                               ui.addEventListener(MouseEvent.CLICK, 
mouseClickHandler);
+                               ui.addEventListener(KeyboardEvent.KEY_DOWN, 
keyDownHandler);
+                       } else {
+                               trace("You need a camera.");
+                       }
+               }
+               
+               private function mouseClickHandler(event:MouseEvent):void
+               {
+                       savePicture();
+                       root.removeChild(ui);
+               }
+               
+               private function keyDownHandler(event:KeyboardEvent):void
+               {
+                       if (event.keyCode == Keyboard.ESCAPE)
+                               root.removeChild(ui);
+                       else if (event.keyCode == Keyboard.ENTER || 
event.keyCode == Keyboard.SPACE)
+                       {
+                               savePicture();
+                               root.removeChild(ui);
+                       }
+               }
+
+               private function savePicture():void
+               {
+                       var f:File = File.createTempFile();
+                       var bd:BitmapData = new BitmapData(camera.width, 
camera.height, false);
+                       var pix:ByteArray = new ByteArray();
+                       var rect:Rectangle = new Rectangle(0, 0, camera.width, 
camera.height);
+                       camera.copyToByteArray(rect, pix);
+                       pix.position = 0;
+                       bd.setPixels(rect, pix);
+                       var png:PNGEncoder = new PNGEncoder();
+                       var ba:ByteArray = png.encode(bd);
+                       var fs:FileStream = new FileStream();
+                       fs.open(f, FileMode.WRITE);
+                       fs.writeBytes(ba);
+                       fs.close();
+                       cameraSuccess(f.url);
                }
                
                public function cleanup( cameraSuccess:Function, 
cameraError:Function ) : void
                {
-                       // stub for JavaScript version
+                       // no cleanup required in Flash
                }
        }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/b83027c6/frameworks/as/projects/FlexJSUI/src/org/apache/flex/utils/PNGEncoder.as
----------------------------------------------------------------------
diff --git 
a/frameworks/as/projects/FlexJSUI/src/org/apache/flex/utils/PNGEncoder.as 
b/frameworks/as/projects/FlexJSUI/src/org/apache/flex/utils/PNGEncoder.as
new file mode 100644
index 0000000..bd1fce4
--- /dev/null
+++ b/frameworks/as/projects/FlexJSUI/src/org/apache/flex/utils/PNGEncoder.as
@@ -0,0 +1,304 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils
+{
+
+import flash.display.BitmapData;
+import flash.utils.ByteArray;
+
+/**
+ *  The PNGEncoder class converts raw bitmap images into encoded
+ *  images using Portable Network Graphics (PNG) lossless compression.
+ *
+ *  <p>For the PNG specification, see http://www.w3.org/TR/PNG/</p>.
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public class PNGEncoder
+{
+
+       // this is a copy of mx.graphics.codec.PNGEncoder
+       
+       
//--------------------------------------------------------------------------
+       //
+       //  Class constants
+       //
+       
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+        *  The MIME type for a PNG image.
+     */
+    private static const CONTENT_TYPE:String = "image/png";
+
+       
//--------------------------------------------------------------------------
+       //
+       //  Constructor
+       //
+       
//--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function PNGEncoder()
+    {
+       super();
+
+               initializeCRCTable();
+       }
+
+       
//--------------------------------------------------------------------------
+       //
+       //  Variables
+       //
+       
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+        *  Used for computing the cyclic redundancy checksum
+        *  at the end of each chunk.
+     */
+    private var crcTable:Array;
+    
+       
//--------------------------------------------------------------------------
+       //
+       //  Properties
+       //
+       
//--------------------------------------------------------------------------
+
+       //----------------------------------
+       //  contentType
+       //----------------------------------
+
+    /**
+     *  The MIME type for the PNG encoded image.
+     *  The value is <code>"image/png"</code>.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function get contentType():String
+    {
+        return CONTENT_TYPE;
+    }
+
+       
//--------------------------------------------------------------------------
+       //
+       //  Methods
+       //
+       
//--------------------------------------------------------------------------
+
+    /**
+     *  Converts the pixels of a BitmapData object
+        *  to a PNG-encoded ByteArray object.
+     *
+     *  @param bitmapData The input BitmapData object.
+     *
+     *  @return Returns a ByteArray object containing PNG-encoded image data.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function encode(bitmapData:BitmapData):ByteArray
+    {
+        return internalEncode(bitmapData, bitmapData.width, bitmapData.height,
+                                                         
bitmapData.transparent);
+    }
+
+    /**
+     *  Converts a ByteArray object containing raw pixels
+        *  in 32-bit ARGB (Alpha, Red, Green, Blue) format
+        *  to a new PNG-encoded ByteArray object.
+        *  The original ByteArray is left unchanged.
+     *
+     *  @param byteArray The input ByteArray object containing raw pixels.
+        *  This ByteArray should contain
+        *  <code>4 * width * height</code> bytes.
+        *  Each pixel is represented by 4 bytes, in the order ARGB.
+        *  The first four bytes represent the top-left pixel of the image.
+        *  The next four bytes represent the pixel to its right, etc.
+        *  Each row follows the previous one without any padding.
+     *
+     *  @param width The width of the input image, in pixels.
+     *
+     *  @param height The height of the input image, in pixels.
+     *
+     *  @param transparent If <code>false</code>, alpha channel information
+        *  is ignored but you still must represent each pixel 
+     *  as four bytes in ARGB format.
+     *
+     *  @return Returns a ByteArray object containing PNG-encoded image data. 
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function encodeByteArray(byteArray:ByteArray, width:int, height:int,
+                                                                       
transparent:Boolean = true):ByteArray
+    {
+        return internalEncode(byteArray, width, height, transparent);
+    }
+
+    /**
+        *  @private
+        */
+       private function initializeCRCTable():void
+       {
+        crcTable = [];
+
+        for (var n:uint = 0; n < 256; n++)
+        {
+            var c:uint = n;
+            for (var k:uint = 0; k < 8; k++)
+            {
+                if (c & 1)
+                    c = uint(uint(0xedb88320) ^ uint(c >>> 1));
+                               else
+                    c = uint(c >>> 1);
+             }
+            crcTable[n] = c;
+        }
+       }
+
+    /**
+        *  @private
+        */
+       private function internalEncode(source:Object, width:int, height:int,
+                                                                       
transparent:Boolean = true):ByteArray
+    {
+       // The source is either a BitmapData or a ByteArray.
+       var sourceBitmapData:BitmapData = source as BitmapData;
+       var sourceByteArray:ByteArray = source as ByteArray;
+       
+       if (sourceByteArray)
+               sourceByteArray.position = 0;
+       
+        // Create output byte array
+        var png:ByteArray = new ByteArray();
+
+        // Write PNG signature
+        png.writeUnsignedInt(0x89504E47);
+        png.writeUnsignedInt(0x0D0A1A0A);
+
+        // Build IHDR chunk
+        var IHDR:ByteArray = new ByteArray();
+        IHDR.writeInt(width);
+        IHDR.writeInt(height);
+               IHDR.writeByte(8); // bit depth per channel
+               IHDR.writeByte(6); // color type: RGBA
+               IHDR.writeByte(0); // compression method
+               IHDR.writeByte(0); // filter method
+        IHDR.writeByte(0); // interlace method
+        writeChunk(png, 0x49484452, IHDR);
+
+        // Build IDAT chunk
+        var IDAT:ByteArray = new ByteArray();
+        for (var y:int = 0; y < height; y++)
+        {
+            IDAT.writeByte(0); // no filter
+
+            var x:int;
+            var pixel:uint;
+            
+                       if (!transparent)
+            {
+                for (x = 0; x < width; x++)
+                {
+                    if (sourceBitmapData)
+                       pixel = sourceBitmapData.getPixel(x, y);
+                       else
+                               pixel = sourceByteArray.readUnsignedInt();
+                                       
+                                       IDAT.writeUnsignedInt(uint(((pixel & 
0xFFFFFF) << 8) | 0xFF));
+                }
+            }
+            else
+            {
+                for (x = 0; x < width; x++)
+                {
+                    if (sourceBitmapData)
+                               pixel = sourceBitmapData.getPixel32(x, y);
+                    else
+                                               pixel = 
sourceByteArray.readUnsignedInt();
+ 
+                    IDAT.writeUnsignedInt(uint(((pixel & 0xFFFFFF) << 8) |
+                                                                               
                (pixel >>> 24)));
+                }
+            }
+        }
+        IDAT.compress();
+        writeChunk(png, 0x49444154, IDAT);
+
+        // Build IEND chunk
+        writeChunk(png, 0x49454E44, null);
+
+        // return PNG
+        png.position = 0;
+        return png;
+    }
+
+    /**
+        *  @private
+        */
+       private function writeChunk(png:ByteArray, type:uint, 
data:ByteArray):void
+    {
+        // Write length of data.
+        var len:uint = 0;
+        if (data)
+            len = data.length;
+               png.writeUnsignedInt(len);
+        
+               // Write chunk type.
+               var typePos:uint = png.position;
+               png.writeUnsignedInt(type);
+        
+               // Write data.
+               if (data)
+            png.writeBytes(data);
+
+        // Write CRC of chunk type and data.
+               var crcPos:uint = png.position;
+        png.position = typePos;
+        var crc:uint = 0xFFFFFFFF;
+        for (var i:uint = typePos; i < crcPos; i++)
+        {
+            crc = uint(crcTable[(crc ^ png.readUnsignedByte()) & uint(0xFF)] ^
+                                          uint(crc >>> 8));
+        }
+        crc = uint(crc ^ uint(0xFFFFFFFF));
+        png.position = crcPos;
+        png.writeUnsignedInt(crc);
+    }
+}
+
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/b83027c6/frameworks/as/projects/FlexJSUI/src/org/apache/flex/utils/ViewSourceContextMenuOption.as
----------------------------------------------------------------------
diff --git 
a/frameworks/as/projects/FlexJSUI/src/org/apache/flex/utils/ViewSourceContextMenuOption.as
 
b/frameworks/as/projects/FlexJSUI/src/org/apache/flex/utils/ViewSourceContextMenuOption.as
index 5dc0a3b..23a1324 100644
--- 
a/frameworks/as/projects/FlexJSUI/src/org/apache/flex/utils/ViewSourceContextMenuOption.as
+++ 
b/frameworks/as/projects/FlexJSUI/src/org/apache/flex/utils/ViewSourceContextMenuOption.as
@@ -69,7 +69,7 @@ public class ViewSourceContextMenuOption implements IBead
                _strand = value;
                
                var menuHost:InteractiveObject = InteractiveObject(value);
-               var cm:ContextMenu = menuHost.contextMenu;
+               var cm:ContextMenu = ContextMenu(menuHost.contextMenu);
                if (!cm)
                {
                        cm = new ContextMenu();

Reply via email to