PNGSizeExtractor

ActionScript, Air, Flash, Flex No Comments »

I was trying to read the dimensions of some very large image files today when I bumped into the Flash Player 10 limitations regarding maximum image sizes. (More info about this is available here.) Since an image file that is too big will not be shown correctly, there is no use in uploading and using it. I wanted to provide detailed feedback about the image dimensions and how they exceeded the allowed sizes, but that was not possible unfortunately since the width and height properties of the loaded image would remain 0. (I posted a question on StackOverflow about this issue here.)

The JPGSizeExtractor class by Antti Kupila enables you to read the width and height of a JPG by reading the image's bytecode. Since we also need to support PNG files, I thought I'd create a simple PNGSizeExtractor myself.

Here's the code:

Actionscript:
  1. package com.herrodius.utils {
  2.    
  3.     import flash.utils.ByteArray;
  4.  
  5.     /**
  6.      * Reads the width and height from a PNG image.
  7.      *
  8.      * http://en.wikipedia.org/wiki/Portable_Network_Graphics
  9.      * http://www.libpng.org/pub/png/spec/1.2/png-1.2-pdg.html
  10.      *
  11.      * @author Christophe Herreman
  12.      */
  13.     public class PNGSizeExtractor {
  14.  
  15.         private static const SIGNATURE_BYTES:Array = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
  16.  
  17.         private static const CHUNK_TYPE_SIZE:uint = 4;
  18.  
  19.         // --------------------------------------------------------------------
  20.         //
  21.         // Constructor
  22.         //
  23.         // --------------------------------------------------------------------
  24.  
  25.         public function PNGSizeExtractor(byteArray:ByteArray) {
  26.             decode(byteArray);
  27.         }
  28.  
  29.         // --------------------------------------------------------------------
  30.         //
  31.         // Public Properties
  32.         //
  33.         // --------------------------------------------------------------------
  34.  
  35.         // ----------------------------
  36.         // width
  37.         // ----------------------------
  38.  
  39.         private var _width:uint;
  40.  
  41.         public function get width():uint {
  42.             return _width;
  43.         }
  44.  
  45.         // ----------------------------
  46.         // height
  47.         // ----------------------------
  48.  
  49.         private var _height:uint;
  50.  
  51.         public function get height():uint {
  52.             return _height;
  53.         }
  54.  
  55.         // --------------------------------------------------------------------
  56.         //
  57.         // Private Methods
  58.         //
  59.         // --------------------------------------------------------------------
  60.  
  61.         private function decode(data:ByteArray):void {
  62.             readSignature(data);
  63.             readIHDR(data);
  64.         }
  65.  
  66.         private function readSignature(data:ByteArray):void {
  67.             for (var i:uint = 0; i<SIGNATURE_BYTES.length; i++) {
  68.                 if (data.readUnsignedByte() != SIGNATURE_BYTES[i]) {
  69.                     throw new Error("File is not a PNG file.");
  70.                 }
  71.             }
  72.         }
  73.  
  74.         private function readIHDR(data:ByteArray):void {
  75.             var size:uint = data.readUnsignedInt();
  76.             var type:String = data.readUTFBytes(CHUNK_TYPE_SIZE);
  77.             _width = data.readUnsignedInt();
  78.             _height = data.readUnsignedInt();
  79.         }
  80.        
  81.     }
  82. }

And here's how to use it. (byteArray is the data of the loaded PNG):

Actionscript:
  1. var pngDecoder:PNGSizeExtractor = new PNGSizeExtractor(byteArray);
  2. trace(pngDecoder.width, pngDecoder.height);

And here is a small sample application that loads the file locally:

Actionscript:
  1. <?xml version="1.0"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="left">
  3.  
  4.     <mx:Script>
  5.         <![CDATA[
  6.         import com.herrodius.utils.PNGSizeExtractor;
  7.  
  8.         import mx.controls.Alert;
  9.  
  10.         private var _fileReference:FileReference;
  11.  
  12.         private function browseButton_clickHandler(event:MouseEvent):void {
  13.             _fileReference = new FileReference();
  14.             _fileReference.addEventListener(Event.SELECT, fileReference_selectHandler);
  15.             _fileReference.addEventListener(Event.COMPLETE, fileReference_completeHandler);
  16.             _fileReference.browse();
  17.         }
  18.  
  19.         private function fileReference_selectHandler(event:Event):void {
  20.             _fileReference.load();
  21.         }
  22.  
  23.         private function fileReference_completeHandler(event:Event):void {
  24.             fileNameTextInput.text = _fileReference.name;
  25.  
  26.             try {
  27.                 var pngDecoder:PNGSizeExtractor = new PNGSizeExtractor(_fileReference.data);
  28.                 textArea.text = "Width: " + pngDecoder.width + "\n";
  29.                 textArea.text += "Height: " + pngDecoder.height;
  30.             } catch (e:Error) {
  31.                 Alert.show(e.message, "Error decoding image");
  32.             }
  33.         }
  34.  
  35.         ]]>
  36.     </mx:Script>
  37.  
  38.     <mx:Label text="Browse for a PNG file." fontWeight="bold"/>
  39.  
  40.     <mx:HBox width="100%">
  41.         <mx:TextInput id="fileNameTextInput" width="100%" editable="false"/>
  42.         <mx:Button id="browseButton" label="..." click="browseButton_clickHandler(event)"/>
  43.     </mx:HBox>
  44.  
  45.     <mx:TextArea id="textArea" width="100%" height="100%"/>
  46.  
  47. </mx:Application>


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 

Spring ActionScript Devoxx slides

ActionScript, Air, Flex, Inversion of Control, Spring ActionScript, Talks No Comments »

Here are the slides of the presentation I did on Spring ActionScript at the Devoxx conference 2009. The sample application will be available in the upcoming 0.9 release, so stay tuned. A pdf version is also available here.

If you have any specific questions you can post them in the comments or check our forum.

Enjoy.


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 

Spring ActionScript at the Devoxx Conference

ActionScript, Conferences, Flex, Spring ActionScript 1 Comment »

devoxxOn November 18th, I'll be doing a presentation on Spring ActionScript at this year's Devoxx conference in Antwerp, Belgium. The conference formerly known as JavaPolis is the biggest European (Java) Developers conference.This 5 day conference has an impressive speaker list each year, lots of quality content and is extremely cheap compared to other conferences. So even with the economic crisis, there is no reason not to be there...

Here's the abstract of my presentation (link):

Spring ActionScript is an offshoot of Java Spring and brings Inversion of Control to the Flash Platform. Primarily focusing on Flex and AIR development, you'll learn how this framework can be used to build testable and maintainable applications. We'll take a look at the different kinds of configuration options and will also see how the minimal MVCS infrastructure fits into an application.

If you're there and are interested in Flex development, then this session is for you.

I'm currently preparing samples and slides, so if you have anything in particular you would like to see covered, feel free to leave something in the comments. Or if you are attending the conference and would like to meet up, leave a comment as well.

Looking forward to seeing you there!


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 

Thoughts on Cairngorm 3 and Application Architecture

AS3Commons, ActionScript, Cairngorm, Design Patterns, Flex, Inversion of Control, Lessons learned, Microsoft, Spring ActionScript 13 Comments »

Cairngorm 3 was recently announced by Tom Sugden and Alex Uhlmann and has now been released in beta on the Adobe Opensource site.

Don't expect an updated version of the Cairngorm framework as you know it though. Cairngorm 3 is not aiming to be an MVC implementation, and thus moves away from what version 1 and 2 were, but now consists of a set of patterns and practices, together with a series of libraries that can help to solve common problems.

The Patterns & Practices Group at Microsoft have been promoting a similar mindset for quite some time actually: Prism - patterns & practices Composite Application Guidance for WPF

I can only encourage this decision as it is exactly how I personally think about application design and architecture, especially in Flex and AIR applications. This is also what we are trying to do with Spring ActionScript: our main goal is to provide a solid Inversion of Control container that supports multiple configuration options (XML, MXML, metadata driven component scanning, ...) and promote it as a foundation to build applications (and frameworks), with or without your favorite MVC framework. Although we are working on a set of base classes that provide infrastructure for your application (under the name MVCS) with Application Events, Controllers, Abstractions for service layers, ... by no means do we want to market the Spring ActionScript framework as yet another MVC implementation. (You might wonder why we are calling it MVCS then, and I'm actually wondering the same... I guess marketing and buzzwords in the opensource world are also important. All kidding aside, the name is certainly subject to change).

What's in a name

Since this is a complete change of direction for the Cairngorm framework (which it actually no longer is) I would have expected a new name. Continuing to use Cairngorm as a name is in my opinion a bad move and will cause major confusion amongst developers and other people involved in the development process. I think the best thing for Adobe, or at least their Technical Services department, would be to let go of the name and choose a new, fresh name that moves away from the past. (Besides that, who can pronounce "Cairngorm".)

Dependencies

I noticed that some of the modules that Cairngorm 3 provides depend on other libraries/frameworks, and in general the Parsley application framework. While Parsley is certainly a major player amongst the IoC/application frameworks, and I sincerely respect the author's work, I don't think this is a good decision. In case you are wondering: Yes, I would say the same thing if they decided to depend on Spring ActionScript.

The usage and choice of a concrete dependency will have consequences for the adoption and integration of the libraries that Cairngorm 3 provides. Think about it: Why would you want to pull in Parsley, perhaps only to use some of its Reflection API, if you are already running on Spring ActionScript or any other IoC container?

We, the Spring ActionScript team, have actually questioned ourselves about this in the past and have therefore decided to move all the common and reusable code from Spring ActionScript into a set of libraries known as the AS3Commons project. In that respect, I'm a bit disappointed that for instance the AS3Commons Reflect library is not used for reflection purposes, since I think it is more abstracted and unintrusive than a subset of an all-encompassing application framework. Perhaps this may be our fault of not promoting the libraries and the project enough. However, I certainly think that AS3Commons could be a wonderful project and would help to provide common libraries not only to Flex and AIR developers, but to ActionScript 3 developers in general, if it were embraced by the community.

Flex and MVC

Given that RIA technolgies are still evolving at a very fast pace, it is really remarkable to see the huge amount of MVC implementations appear. Not specifically aimed at Cairngorm (at least the previous versions), but rather at almost all MVC architectures available for Flex development, my personal feeling and experience is that the use of MVC architectures in the Adobe RIA space is almost a dogmatic thing and is not needed in most cases. The problem is that people just take an MVC framework as it is and implement it in their applications. More than often not questioning whether or not its usage is justified. Things that could easily and cleverly be solved are ripped apart across layers of the architecture, introducing levels of indirection that are in most cases not needed. The only thing they add is complexity and counter-intuitive development practices.

One of the main arguments for using an MVC framework is that the code is "easy to understand". Of course the code will be easy to understand if you have been developing with the framework of choice for the N-th time or if you have been digging into the code for a serious amount of time, but ask a newcomer to look at the code and try to explain to you what it is actually doing... I think you'll be surprised by the responses.

I'm not saying that the use of a particular MVC framework is de facto a bad thing, but the "religious" use and the blind adoption and implementation make a framework a killer for your application. I would encourage everyone to start their next project without an MVC framework and just use the Flex framework with a healthy knowledge of design and presentation patterns. And even if you are using an MVC implementation, think about each layer you introduce, why you need it and the pros and cons it brings.

Conclusion

It's good to see that Adobe is rethinking their approach to RIA architecture and development practices. I also hope that they will be more open to community input and feedback than they were in the past. Although they did several attempts at engaging the community, I don't think they really succeeded in that. If not open enough, people will just continue to fork the "framework" and provide extensions that will end up in alternative implementations anyway.

I'm looking forward to seeing how all of this evolves.


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 

Spring ActionScript 0.8.1 Released

ActionScript, Air, Flash, Flex, Spring ActionScript 4 Comments »

Dear Community,

I'm pleased to announce that the Spring ActionScript 0.8.1 release is now available.

Download | API Documentation | HTML Docs | PDF Docs | Changelog

This release includes the Spring ActionScript framework, the Cairngorm extensions and the PureMVC extensions and is mainly a bugfix release based on user feedback, for which we are very grateful.

Besides a series of bugfixes, we have also refactored the stage wiring system a bit so it now enables you to extend it with custom functionality. Two proof-of-concept implementations were added, namely the LocalizationStageProcessor and the SimpleSecurityStageProcessor.

LocalizationStageProcessor

This first processor enables you to assign resource values to components that are added to the stage, thus removing the need to add binding code for components at design-time. The values are assigned on a simple 'configuration-by-name' basis: a resource string in the form 'myButton_label=Click me' will assign the value 'Click me' to the label property of a stage component with the id 'myButton'.

There's a small sample app as well showcasing the localization processor.

SimpleSecurityStageProcessor

The second processor is slightly more elaborate and offers runtime security/authorization functionality.

There's also a small sample application for this processor.

Basically what this processor does is create an ISecurityManager instance for a given component that is added to the stage. (Whether or not this creation will be considered is determined by the approval result of an IObjectSelector). This ISecurityManager holds a list of role and right names that are applicable for the specified stage component and is able to block access to the component after evaluation of these security rules.

The way to block access is determined by the AccessStrategy enum, that is part of the SimpleStageSecurityManager implementation of the ISecurityManager. It can set the enabled property to false, or visible to false, etc. The implementation of these security interfaces is SIMPLE, hence the names. For now, we didn't want to include a very elaborate implementation since security can vary very widely from application to application. These interfaces are really meant as a 'roll-your-own' package, Spring ActionScript just offers the infrastructure in this case.

Last Words

Although this is a minor release, we would recommend all users to upgrade.

Further, we are always looking for user feedback and input. Be it bug reports, patches, new ideas, etc, all help is welcome. If you think you can contribute to the project in whatever way, don't hesitate to leave something in the comments or mail me at christophe [DOT] herreman [AT] gmail [DOT] com.


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 
WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in