2009
10.02

I recently have been working an AIR application and hit a wall fast when the PDF load portion of the app kept crashing when the PDF would load in. Of course I spent a good day trying to figure this out. I jumped on this thread and had a few email conversations with members of the AIR team. Finally it was confirmed that this is a SnowLeopard and AIR compatibility issue. Everything else seems to be working fine in SL, but of course the app I’m working on uses features with issues. sigh… Anyway, I hope this saves someone a headache.

2009
08.24

There are many cool server-side image manipulation libraries out there including the very popular GD for PHP. The problem is that your server has to have it installed for you to be able to utilize it and if your server does not ( and you don’t admin your own), it’s often difficult or even impossible for you to install it yourself. Another pitfall of using the server-side approach for image processing is that you still have to upload the image before it can be processed, and with cameras these days, end users will most likely upload some pretty large images.

Ideally we would process the image locally before sending it to the server. I did some hefty research and found a lot of cool things we can do in the flash player, but no solid step by step to doing exactly what I wanted to achieve. My goal was to do the following.

1. Allow user to browse for image on their local system
2. Convert file reference into BitmapData
3. Scale BitmapData to fit inside a MAX resolution
4. Compress and encode the BitmapData into a ByteArray
5. Send ByteArray to server-side script to create and save the image file

After finding several articles covering pieces of these steps, I was able to stitch together the code to achieve the above goal. To use my code examples, you will need to use Flex 3 targeted for Flash Player 10 and Zend AMF to send the image data to your server.

<?xml version=“1.0″ encoding=“utf-8″?>
<mx:Application xmlns:mx=“http://www.adobe.com/2006/mxml” layout=“absolute”>

        <mx:Script>
                <![CDATA[
               
                        import mx.graphics.codec.JPEGEncoder;
               
                        private var _fileRef:FileReference;
                        private var _netConnection:NetConnection;
                        private var _imageByteArray:ByteArray;
                       
                        private static const MAX_SIZE:Number = 300;
                       
                        private function getFile():void{
                                _fileRef = new FileReference();
                                _fileRef.addEventListener(Event.SELECT,onFileSelect);
                                _fileRef.browse();
                        }
                        private function onFileSelect(e:Event):void{
                                _fileRef.addEventListener(Event.COMPLETE,onFileLoad);
                                _fileRef.load();
                        }
                        private function onFileLoad(e:Event):void{
                                var loader:Loader = new Loader();
                                loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
                                loader.loadBytes (_fileRef.data);
                        }
                        private function onImageLoaded(e:Event):void{
                                var loadedBitmap:Bitmap = Bitmap(e.target.content);
                                var scale:Number = getScale(loadedBitmap);
                                var bmpData:BitmapData = new BitmapData(loadedBitmap.width * scale, loadedBitmap.height * scale,false);
                                var matrix:Matrix = new Matrix();
                                matrix.scale(scale,scale);
                                bmpData.draw(loadedBitmap,matrix)
                                var jpg:JPEGEncoder = new JPEGEncoder(60);
                                _imageByteArray = jpg.encode(bmpData);
                                uploadImage();
                        }
                        private function getScale(img:Bitmap):Number{
                                var scale:Number;
                                if(img.width > MAX_SIZE){
                                        scale = MAX_SIZE / img.width;
                                }
                                else if(img.height > MAX_SIZE){
                                        scale = MAX_SIZE / img.height;
                                }
                                else{
                                        scale = 1;
                                }
                                return scale;
                        }
                        private function uploadImage():void{
                                _netConnection = new NetConnection();
                                _netConnection.connect(‘http://localhost:8888/_PHP/classes/’);
                                var res:Responder = new Responder(onDataResult, onDataError);
                                _netConnection.call(“KingHippo.saveImage”,res,_imageByteArray);
                        }
                        public function onDataResult(obj:Object):void{
                                trace(obj);/////FILE SAVED
                        }
                        public function onDataError(obj:Object):void{
                                trace(‘error’);///////OOPS
                        }
                ]]>
        </mx:Script>

        <mx:Button label=“browse” click=“getFile()” />

</mx:Application>

That pretty much wraps up the Flex code. I’ll explain the code referring to our original goal list.

1. Allow user to browse for image
Here we have a simple Button that calls a function that will instantiate a file reference object and use its browse() method to prompt the user with their local file browser.

2. Convert file reference into BitmapData
Upon file select, we will need to get this file loaded in to grab its BitmapData. This is where Flash Player 10 comes in. We now have some cool FileReference additions to play with and can now load in the file selected. First we call the load() method. When COMPLETE, we have access to the data of that file which means we can use a Loader to load the bytes of the data using the loadBytes() method from our Loader.

3. Scale BitmapData to fit inside a MAX resolution
OK, so now we have our image data and its time to do some BitmapData trickery. First we need to set the incoming data to a Bitmap object. Next we determine how much we need to scale down the image by using our MAX_SIZE variable. Here I’m using 300 so the width or height will not exceed that number. Once I determine the scale value (using the getScale function) , I can now create and manipulate my Bitmap Data. I create a new BitmapData object and set it to the appropriate size using my scale value against the image’s original size. Now I need to draw from the loaded image. It’s not enough to just draw it b/c it will just grab that rect from the original image data, essentially cropping it. We need to use Matrix to set the scale of the original data within our draw() method.
Now we have our image data and appropriate resolution.

4. Compress and encode BitmapData into a ByteArray
Next, using Flex’s JPEGEncoder, we can compress the data and encode it to a ByteArray. Simply create a new JPEGEncoder object and pass a quality value to its constructor. The values are 1 – 100. Here I’m using 60. Then we call the JPEGEncoder’s encode() method which will then give us our long-awaited ByteArray. Now we can pass it on to the server.

5. Send ByteArray to server-side script to create image file
Lastly, we need to send off the image data to the server. Here I’m using Zend AMF and sending the ByteArray to a PHP class.

Now we are done on the Flex end. The last thing we need to do is create the image file from the data sent to the server and save it.
PHP code below..

<?php

class KingHippo{       
       
        public function __construct(){
                //////construct
        }
        public function saveImage($obj){
                $fp = fopen(‘myNewImage.jpg’, ‘wb’);
                fwrite( $fp, implode(,$obj));
                fclose( $fp );
                return “FILE SAVED”;
        }
}

<?

That’s pretty much it. You’ll most likely want to add to it by sending a unique path and file name for the saved image.

2009
08.04
Column View File Browser v.1

Column View File Browser

I’ve been starting and stopping this AIR application idea I’ve had for a while which is, in a nutshell, some sort of super local file manager. I’m always creating and moving around Finder windows to fit a specific need or project so I think it would be nice to have an app that will handle all of that in one application window. I’ve used SQLite for other AIR apps so adding ‘Favorites’ and ‘Preferences’ should make this application fairly decent. I’m sure these sorts of applications exist but I think it would be the perfect project to gain some more AIR skills.

Recently I decided to pick it back up and try to actually finish it. This time I’m starting over from scratch and hopefully I’ll remember all of the ‘gotchas’ when creating this in Flex that made me give up some many times in the past. The first thing I decided to do was to make a better file browser that will be used for the windows in my app. I’m not really all that happy with the packaged FileSystem.. Flex components so I decided to create one. I’m a huge fan of the column view in Finder on a Mac, so I decided to mimic this approach.

A snapshot of the component so far is above.

I call this ‘part one’ because I have not gotten too much into skinning etc on this one, but I plan on doing that next. I can already see the cool things I’ll be able to do with it now that the base functionality is complete. I’ll be using icons for the files in the lists as well as image, video, and sound previews in the file info columns. Should be pretty fun.

Do I dare create a Cover Flow version as well?? Eh, sounds like a pain in the ass.

Grab Source

2009
07.23

I was lucky enough to get a free Adobe CS4 upgrade so I installed it the day it was released – (on my birthday) – so it’s hard to say how soon I would’ve finally upgraded if that hadn’t been the case. Having used it for about 9 months now, I’d say that there are just enough features in Flash to where I couldn’t go back to using Flash CS3…but not much.

First and foremost is the Library Search. This has become crucial to my workflow and I don’t know how I survived without it. Another one worth mentioning before I go on is the ‘Show in Library’ feature. If you see it on stage, you can gain quick access to it in your library which is another feature that helps a lot, especially when taking over flash projects.

That being said, I thought I’d come up with a wish list of what I hope to see in Flash CS5. I’ve submitted my full list to Adobe but thought I’d share my top 5 with you.

1. Better folder creation in the Library
I’ve become pretty anal with my library these days. I go as far as to package my movie clips to match the packages of their corresponding classes. This helps me stay organized but creating those folders inside the library is a pain in the ass (at least on a Mac). If you select a folder, then click the new folder icon, it won’t put the new one INSIDE the folder you selected. With long libraries, it’s such a pain to go all the way to the bottom, find the new folder, then drag it where you want it. I know there is the Move To… option, but still, why the extra step?

And please add Right Click (on folder) -> New Folder.

2. Update Bitmap from Stage
Or at least from the ‘other’ properties panel. Getting revisions is a common thing in this field and the ‘Update’ feature on bitmaps really helps out. But most of the time you also have to get to it on the stage to see the result of the update, so it’d be nice to just do the update from there and not have to dig around in the library. At least the ‘Show in Library’ feature helps out on this one, but it’s still an extra step.

Right Click -> update……. or at least….. select symbol, click ‘Update’ from properties panel (currently only has ‘Edit’ and ‘Swap’).

3. Generate Class for Movie Clip.
I’d be nice if Flash could start a class for me. Currently, you open its properties, check Export for Action Script, write in your package, go over to another editor and create that class.(or the other way around) It would be very cool if Flash could create that file for you if you opt to write the class.

So instead of the current alert:

A definition for this class could not be found in the classpath, so one will be automatically generated in the SWF file upon export.

How about:

A definition for this class could not be found in the classpath.
Would you like Flash to create one upon export OR generate the script?

In doing so, Flash would start the class file and create the package directories if they don’t currently exist.

4. Edit Class……..in Flash Builder
You can open a class file in CS4 by pressing the pencil icon inside a Movie Clips properties. Of course this opens in Flash, but with the new Flash Builder, I really hope you have an option to have it open inside of there. And again, let me access its class, or edit the path, without having to first find it in the library.

This feature also goes for double clicking on compiler errors.

5. Relative source paths.
This one really pisses me off. I often find myself passing an FLA back and forth with timeline animators and designers, but the thing won’t publish if it can’t find my scripts. Flash puts in an absolute path here (again – at least on a Mac), which makes sense for cross-project settings, but it gets old when both parties have to change the path to scripts right next to it everytime they get an updated FLA.

I have a few more, like a preference to ‘never automatically declare stage instances (for all projects)’, but those are mostly ‘kind of’ important issues.

Please, if any of these things ARE doable, or if you have found a nice solution, respond with them here. Also, are any of these issues not present on a PC?

2009
07.10

I came across a snag that took me by surprise while developing our Band Beast Administration. The admin has several views and forms in it and they all basically have the same logic, but different visuals. I write base classes all the time in my Flash development, but hadn’t attempted to do this with MXML components in Flex. I wrote my base component that would handle common logic and display common visuals and then I created my first component that would extend this base class. The MXML looks like this:

ChildView.mxml – extends BaseView

<?xml version=“1.0″ encoding=“utf-8″?>
<BaseView xmlns=“*” xmlns:mx=“http://www.adobe.com/2006/mxml”
        width=“400″ height=“300″>
</BaseView>

This works fine and when adding this component to my Application, it looked and worked the same as my base class. The next logical step, or so I thought, would be to start adding my visual elements in the MXML of my sub component.

<?xml version=“1.0″ encoding=“utf-8″?>
<BaseView xmlns=“*” xmlns:mx=“http://www.adobe.com/2006/mxml”
        width=“400″ height=“300″>
        <mx:Text text=“I am a CHILD” />
        <mx:ComboBox />
</BaseView>

When compiling, I got an unexpected error:

Error: Multiple sets of visual children have been specified for this component (base component definition and derived component definition).

So this means I can extend a MXML component, but I can’t add visual components to it? Seems strange to me; why else would you extend a component? After researching, I found out that allowing this approach was a hot debate when developing Flex Builder and Adobe ultimately decided not to allow this procedure. Instead, they suggest you use what they call ‘Component Templating’. To do this you must first wrap the visual children inside of your sub component inside a tag in your MXML. You can call this tag whatever you want but in this example I called it ’subComponents’.

<?xml version=“1.0″ encoding=“utf-8″?>
<BaseView xmlns=“*” xmlns:mx=“http://www.adobe.com/2006/mxml”
        width=“400″ height=“300″>
        <subComponents>
                <mx:Text text=“I am a CHILD” />
                <mx:ComboBox />
        </subComponents>
</BaseView>

Notice you’ll get the following error inside of Flex Builder

Error: Could not resolve subComponents to a component implementation

This is because you need to declare ’subComponents’ in your base component. At this point, ’subComponents’ is an array that holds all of the display children in your sub component. We need to declare this variable in our base class as well as create our Setter function so its value will be set.

our BaseClass – extends Canvas

<?xml version=“1.0″ encoding=“utf-8″?>
<mx:Canvas xmlns:mx=“http://www.adobe.com/2006/mxml” width=“400″ height=“300″>
        <mx:Script>
                <![CDATA[
                         private var _subComponents:Array;
                       
                        public function set subComponents(a:Array):void{
                                _subComponents = a;
                        }
                ]]>
        </mx:Script>
        <mx:Text text=“I am the MASTER” />
</mx:Canvas>

Now we’ve killed our error and Flex is happy. Lastly, we need to actually add these children to the stage by writing a function that fires on the ‘creationComplete’ event in our base class.

<?xml version=“1.0″ encoding=“utf-8″?>
<mx:Canvas xmlns:mx=“http://www.adobe.com/2006/mxml” width=“400″ height=“300″ creationComplete=“addSubComponents()”>
        <mx:Script>
                <![CDATA[
                         private var _subComponents:Array;
                       
                        public function set subComponents(a:Array):void{
                                _subComponents = a;
                        }
                        private function addSubComponents():void{
                                for(var i:int=0; i < _subComponents.length; i++) {
                                   addChild( _subComponents[i] );
                                }
                        }
                ]]>
        </mx:Script>
        <mx:Text text=“I am the MASTER” />
</mx:Canvas>

Now we’ve successfully extended a MXML component. This may sound like a ‘work around’, but in the end it makes sense. Plus the cool part is that now we can add these sub components inside a styled or skinned container — hence the title ‘Component Templating’.

////inside our addSubComponents loop
someCoolContainer.addChild( _subComponents[i] );
2009
07.09

I’m certainly not a fan of anything writing out code for me, but when it comes to Getter and Setter functions, it can get a bit tedious.  Flash Builder 4 comes with a command that will generate that code for you. To do so, position your cursor inside your variable, then select Source->Generate Getter/Setter. It even adds the underscore before your private variable, which I do anyway so I like that. This is all great, but I can’t stand the way Flash Builder formats code.  There seems to be two camps when it comes to code formatting. One places opening curly braces on the next line, the other does not. Here is a great post by Grant Skinner on the topic.  Personally, I keep the open curly brace on the same line and Flash Builder does not. I’ve come to just deal with reformatting when FB creates my new classes, it’s like second nature now, but now that I have this getter/setter feature, I’d really like to change the way it formats.

FB4 also has an Event Handler Generator which comes up in your code hinting inside MXML.

2009
07.08

This is my first blog post ever so I thought I’d start out with something pretty simple.

I recently discovered a nice, and not so obvious, key command in Flash Builder to import classes. It’s no secret that when using Flash Builder’s auto completion after the ‘new’ keyword, it will import that class for you, but what about when using static classes like Tweener, Sound Mixer, or File?  I often find myself in the middle of writing a function and having to stop, go to the top of my script, and import the static class I want to use. How can I get Flash Builder to import this class for me without having to interupt my flow? Simply press Cntrl + Space (Mac and PC) when the cursor is positioned direclty after the class name and Flash Builder will import the class.