Archive for the ‘APPLICATIONS’ Category
A great Action Message Format (AMF) remoting kit for server side for the pythonistas is pyAMF, they recently released PyAMF 0.3 and have a sample running up on Google App Engine. There is also a tutorial for getting PyAMF running on Google App Engine. Aral Balkan got this running as well.
Features of pyAMF currently:
AMF0 encoder/decoder for legacy Flash Players (version 6-8).- AMF3 encoder/decoder for the new AMF format in Flash Player 9.
- Support for IExternalizable, ArrayCollection, ObjectProxy, ByteArray (with zlib support), RecordSet and RemoteObject
- Remoting gateways for Twisted, Django, TurboGears2, Web2Py, Pylons and any compatible WSGI framework.
- Authentication/setCredentials support
- Remoting client using httplib with authentication support
- Service Browser (DescribeService header) requests supported
- Local Shared Object (LSO) support
- Adapter Framework to integrate nicely with third-party Python projects
More on the PyAMF library:
- Download — Download PyAMF
- Examples — Tutorials and examples
- Features — PyAMF features
- Documentation – General documentation
- Mailing List — Join the mailinglist for user and developer discussions
- Blog — Announcements and news
- IRC Channel — Chat and discuss PyAMF or get support
- Success Stories — See how PyAMF is being used
- Team — The people working on this project
- License — The project is licensed under the open source MIT license
If there ever was a proof that more intense applications like word processors and image manipulation software are capable of being built and some aspects even better than their desktop counterparts with flash and flex then Scrapblog, Buzzword, Picnik and Photoshop Express are that (in fact Photoshop Express is a direct competitor with Picnik it seems…).
Adobe launches Photoshop Express today to add to that set that are very usable, quality applications built with Flash9/Flex and most of all actionscript 3 (as3) and the new AVM2. These apps just weren’t possible with AS2 and with Flex they can be easily managed codebases (one major problem with old skool flash actionscript is it was throwaway many times because it was so scripter specific and full of optimizations just to barely perform – now these are actual code bases made by programmers and you see the results). The great thing about buzzword, picnik and photoshop express are that they are easy to use. Flash/Flex make sense in their case and they tend to mimic and use very good usability patterns.There is no way an AJAX app (even though I build lots of those too) can come close to this integration of style, usability and expected results on all browsers.One important point of this article on news.com mentioning this:
The service will go live in beta test mode on Thursday. Mack said that the company intends to use the test period as a way garner feedback from customers.Adobe intends to offer more features to consumers who pay a yearly fee. Some planned features include a printing service, more storage, support for audio and other media, and the ability to read additional image file types (the service works with .JPGs now.)Adobe also plans to build an offline client using AIR (the Adobe Integrated Runtime) so that people can edit photos offline, executives said.
A couple things here. First there is going to be an AIR version for the same experience on the web and the desktop for a major application. Second, flash IS limited to certain file types JPG, SWF, PNG, GIF, and a few others for sound and video. So why an online photoshop is great, it is still only web based photos, simple edits, etc. Photographers and users above 72dpi in the 300 600 ++ ranges will still be using Photoshop. Users with EPS,RAW, etc will still have to use Photoshop until Adobe figures a way to either proxy an image and handle the real source (be it another format) behind the scenes. Or, improve the flash player to handle other raster and vector image types.A project a while back we had this issue where it was a approval system of media types but the types could be PDF or EPS in addition to web image formats or on occasion other formats and it became a challenge where the content was marked up with flash. Eventually it was in a div overlay so we could load in the unsupported types behind and sync them with javascript, where flash was just a canvas or screen on top to put notes and markings. But when it comes to editing that is different, you expect to edit. Also, working with the real source in image manipulation is extremely important so a proxy to the real image seems unlikely a good choice except for simple web uses.In any case, Photoshop Express is a great web based image tool but there are limitations that prevent it from taking any large swath of share from the normal old desktop Photoshop any time soon.
Rostislav added a sample for his excellent SWFAddress kit using the new YouTubeAPI and deep linking to parts of the video. Part of the YouTubeAPI is by Geoff Stearns (the creator of SWFObject who works at YouTube now) and allows much more script control and embedding of the youtube player (chromeless with just the video canvas).
The sample Rostislav at Asual has, shows how you can incorporate SWFAddress now that the youtube player can be embedded by script, and thus how it can have deep-linking to sections of the video from the url.
So, today I spent some time trying to integrate SWFAddress with the sample YouTube video and the result is now available online. There were some tricky parts and probably the code can be encapsulated better, but overall I’m satisfied with the result. Every pause action or significant jump in the playback produces a deep link which will definitely make sense for long videos or specific scenarios. If you want to automatically start the video from the second verve just try this deep link. For this case I decided that it will be better to disable the generation of browser history and the SWFAddress strict mode.
The sample is available in the SWFAddress repository and will become a part of the upcoming 2.1 release.
The cool part about all this is is makes it extremely easy to add commenting at moments in time throughout youtube videos, enables deep-linking, allows snapshots of not just the flash application but also the video that might be playing in that chapter. This is done on services like viddler and others but now you can do it for youtube videos and this will also possibly start a standard way to do this across media players so that a platform of video commenting emerges.
The integration of SWFAddress is simple, on the normal onSWFAddressChange you just pass in the value to the seekTo call:
function onSWFAddressChange(event) { time = seek = parseInt(event.value); ytplayer = document.getElementById('myytplayer'); ytplayer.seekTo(time, true); }
Google video always had jump to time params like:http://video.google.com/videoplay?docid=-5830318882717959520#01m30s (this is a classic/hilarious Erlang video)
…but this is not very workable with the google video player, also you can always add this to other players but having this ability for youtube is a great leap in allowing a more integrated commenting, chapter and community like feel to video.
Since youtube is so big finally having some more control with the YouTubeAPI will allow much more great additions to the capabilities of using youtube video in many more ways and integration of more great javascript kits like SWFAddress.
The YouTube API is really quite useful. Here are some links of interest:
AIR 1.0 and Flex 3.0. have launched.
AIR is finally 1.0 and live as well as Flex3, both launched today. That is quite a 1-2 punch. These are both great technologies and AIR extends the reach to the desktop and lots of power with that being finally 1.0 and officially launched. It has been hard to convince people to develop on it other than tech demos and prototypes, this should help.
Ajaxian has the run down:
Adobe AIR
The AIR runtime and SDK has gone through an especially long beta cycle (since June 2007) to ensure that both security and compatibility with existing frameworks was achieved. Some key new and/or updated features include:
- Enhanced Desktop Fucntionality: Drag and drop to the operating system, copy and paste between applications, launching of AIR applications from the desktop or the browser, and run in the background with notifications.
- Data Access: Adobe AIR now provides both synchronous and asynchronous access to the local file system, as well as structured data within a local database. This database is implemented using the open source SQLite database.
- JS Library Support: Most major Ajax frameworks can be used to build AIR applications. Supported frameworks include jQuery, Ext JS, Dojo, and Spry. Adobe AIR integrates JavaScript and ActionScript to allow cross-scripting between the two languages, and integrated rendering of Flash and HTML content.
- Security: Applications built on Adobe AIR can only be installed through a trustworthy install process that verifies that the application is signed via industry standard certificates, providing users with information about the source and capabilities of the application.
Flex 3.0
Adobe’s Flash-based RIA development platform, Flex, continues to mature and has been picking up steam in both the corporate space as well as sites such as blist and Scrapblog who have embraced Flex whole-heartedly. Some of the new features in Flex 3.0 include:
- Intelligent coding, interactive step-through debugging, and visual design of user interface layout
- New capabilities for creating RIAs and building applications on Adobe AIR
- Integrates with Adobe Creative Suite® 3 making it easy for designers and developers to work together more efficiently.
- New testing tools, including memory and performance profilers and integrated support for automated functional testing, speed up development and lead to higher performing RIAs.
One of the most compelling parts of the Flex announcement is the fact that Adobe has released the Flex SDK under the open source Mozilla Public License.
AS3 libraries for crypto are pretty robust from the new RAW POWER in the AVM2 virtual machine that runs flash9/as3, cryptography, like compression, is very processor intensive and needs a fair amount of power to be worth the time (usually a balancing mechanism). I am working on a few security apps in AIR and Flash9 for a project and a product so this is the best of what I have found to share. I will be sure to post here when these projects are complete.
There are two that are pretty good as3 kits that have decent support for crypto and hashing, actually as3crypto is quite broad in their support or most common crypto algorithms, even hashing support up to SHA-256 and ciphers 3DES, AES, RC4.
This is not really a comparison just some kits that have tools you might need. as3crypto is definitely the way to go for more heavy ecryption with common ciphers, but if you are just hashing some text as3corelib might work for your project. as3corelib is a more broad toolkit that is made or sponsored by Adobe that has JSON, RSS, support and other tools. It is a great core lib, but not as deep in the encryption area. I am actually using both in the stuff I am working on, as3corelib for some other uses (JSON,RSS) and as3crypto for all encryption and hashing.
The two are:
- as3corelib
- Open source
- Support for hashing algorithms only.
- Browse source
- as3crypto
- Robust, broad encryption and security support
- Open source
- Demo
- Browse source
- Broad support of algorithms
-
-
TLS 1.0 support, exposed through TLSSocket and TLSEngine classes
-
X.509 Certificate support, including parsing, and validation
-
built-in list of common root Certificate Authorities
-
symmetric ciphers: AES, Blowfish, DES, 3DES, XTEA, RC4
-
confidentiality modes: CTR, CBC, CFB, CFB-8, OFB, ECB
-
public key crypto: RSA (encryption, decryption, signing, verifying and key generation)
-
padding: PKCS#1 (type 1 and 2), PKCS#5
-
BigInteger library
-
hashing function: SHA-256, SHA-224, SHA-1, MD5, MD2
-
HMAC support
-
prng: TLSPRF and stream-cypher-based PRNG.
-
minimal ASN-1/DER support for PEM key parsing and X-509 cert parsing
-
Crypto – Shortcut class to access many classes above.
-
Hex, Base64 – Static methods to convert binary data to and from text formats
-
-
As3 Crypto is a cryptography library written in Actionscript 3 that provides several common algorithms, as well as TLS 1.0 support. The library is offered under the BSD license, and include several derivative works from Java, C and javascript sources.
Here’s some numbers from as3Crypto home page that show the speed, note it has not been optimized just yet (since most of this is client side and only one user would be using it this is not an issue – server side is where this can have scale problems from parallel execution but flash is rarely server side if it is too slow, but it is quite fast)
The 'numbers' are in 1000s of bytes per second processed. type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes md2 1.01k 3.64k 15.08k 53.89k 171.76k md5 221.85k 447.32k 739.54k 893.72k 905.82k sha1 82.28k 184.78k 286.76k 336.03k 345.41k sha224 60.84k 125.67k 200.27k 234.28k 247.58k sha256 60.52k 126.30k 199.19k 234.04k 246.01k hmac-md5 48.37k 159.37k 282.87k 295.15k 341.21k hmac-sha1 18.29k 64.82k 165.72k 277.60k 342.52k hmac-sha224 5.75k 24.84k 125.71k 204.35k 256.36k hmac-sha256 15.10k 49.33k 123.71k 206.17k 249.08k rc4 117.24k 381.34k 878.93k 1315.01k 1539.44k xtea-cbc 2.49k 6.48k 12.80k 33.00k 44.48k aes128-cbc 1.61k 4.01k 22.97k 78.55k 205.01k aes192-cbc 1.34k 5.13k 20.91k 69.45k 172.43k aes256-cbc 1.48k 5.63k 18.87k 63.45k 150.39k blowfish-cbc 2.77k 10.81k 42.28k 140.27k 343.05k des-cbc 2.53k 9.73k 35.20k 124.84k 624.88k 3des-cbc 2.50k 9.72k 35.61k 115.21k 253.42kThe library has not been optimized for speed, and those numbers could probably be improved.
They both have minimal or none ASN.1 support which I will need but I can port much of this from my favorite Java/C# crypto kit from the legion of the bouncy castle of which I was happy to find was a substantial base for this kit.
Whatever you do don’t send any type of message from your crypto kits with aes 256 cipher and sha-256 hashing to Iran from the US.
Mike Chambers has a great post on parsing RSS in AS3 with as3syndicationlib. I had some info on this in development but Mike’s post is very simple and just posting the code here for reference.
import com.adobe.utils.XMLUtil; import com.adobe.xml.syndication.rss.Item20; import com.adobe.xml.syndication.rss.RSS20; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; import flash.net.URLLoader; import flash.net.URLRequest; import flash.net.URLRequestMethod; private var loader:URLLoader; //url of rss 2.0 feed private static const RSS_URL:String = "http://feeds.feedburner.com/MikeChambers/"; //called when user presses the button to load feed private function onLoadPress():void { loader = new URLLoader(); //request pointing to feed var request:URLRequest = new URLRequest(RSS_URL); request.method = URLRequestMethod.GET; //listen for when the data loads loader.addEventListener(Event.COMPLETE, onDataLoad); //listen for error events loader.addEventListener(IOErrorEvent.IO_ERROR, onIOError); loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError); //load the feed data loader.load(request); } //called once the data has loaded from the feed private function onDataLoad(e:Event):void { //get the raw string data from the feed var rawRSS:String = URLLoader(e.target).data; //parse it as RSS parseRSS(rawRSS); } //parses RSS 2.0 feed and prints out the feed titles into //the text area private function parseRSS(data:String):void { //XMLSyndicationLibrary does not validate that the data contains valid //XML, so you need to validate that the data is valid XML. //We use the XMLUtil.isValidXML API from the corelib library. if(!XMLUtil.isValidXML(data)) { writeOutput("Feed does not contain valid XML."); return; } //create RSS20 instance var rss:RSS20 = new RSS20(); //parse the raw rss data rss.parse(data); //get all of the items within the feed var items:Array = rss.items; //loop through each item in the feed for each(var item:Item20 in items) { //print out the title of each item writeOutput(item.title); } } private function writeOutput(data:String):void { outputField.text += data + "\n"; } private function onIOError(e:IOErrorEvent):void { writeOutput("IOError : " + e.text); } private function onSecurityError(e:SecurityErrorEvent):void { writeOutput("SecurityError : " + e.text); }
Check out the full post on this at Mike’s blog.

Just recently through the holidays Degrafa has made some great strides as a very cool SVG pathing and designers toolkit for Flex. I have to say some recent Flex apps have really looked good like Picnik and Buzzword but this kit looks to clean up the lack of design and default style-itis that has plagued most common Flex Apps.
This so far looking like a pretty strong kit for bringing the designer pipeline into Flex to provide some really nice looking web styled apps. It has a direct crossover to Silverlight and Path objects that are largely just a series of data created in Expression or exported from Illustrator into XAML. The one benefit of Flex/Flash is it compiles to a very small SWF where with Silverlight you have to package the XAML in a zip and use the downloader object to extract it out. These XAML files and Paths can get massive as I am sure the ones for Degrafa will for Flex but the compile option is nice as it is compressed heavily.
All about Degrafa
Yes the launch includes shiny buttons…

Sphere Sample (right click for source)
Also, it appears it is a way to bridge the pathing and pipeline for flash or Silverlight. At one of the contributors blogs they mention this:
We have lot of interesting features planned for the coming releases. There is also a converter app that will be made available for converting the juicy Degrafa graphics to XAML.
Degrafa has gone live.
Developing…
Wrapper is a cross-browser compliant HTML/CSS rendering engine written in ActionScript that sits on top of your standards compliant HTML page. Wrapper eliminates cross-browser issues and makes integrating ActionScript and HTML/CSS projects possible without needing to compile.
Wrappers strives to answer the most common problems web designers face without forcing them to learn too many new things. Most web sites can be created in HTML or CSS, then when you need to extend Wrapper’s capabilities you can either use JSON to call functions within ActionScript or you can load compiled plug-ins. Wrapper also has built in methods within CSS to load custom fonts, display elements as any shape, and fill them with linear or radial gradient background colors. ActionScript’s event model is also implemented within Wrapper’s HTML. Wrapper’s best features are the ones that you get for free because of how it is set up. It’s like getting all the great features of the Flash Player without needing to deal with compiling and being able to create your content the same way any HTML page would be created. Wrapper is fully accessible to the search engines and integrates well with any back-end technology.
Wrapper is currently released as a fully functional open source beta for Flash Player 9. Wrapper is set up as a pre-compiled plug-in but can easily be integrated into any Flex or AIR applications or even as an ActionScript framework for creation of compiled projects.
Documentation can be found in the wiki and news about this project can be found at http://motionandcolor.com
Examples can be found in the downloads http://code.google.com/p/htmlwrapper/downloads/list
Source is for everything is in svn http://code.google.com/p/htmlwrapper/source
I checked it out and it looks pretty well done, most of the time HTML to Flash or vice versa has to be a semi-controlled environment in terms of the markup. This and FlashML which is only AS2 I am using a partially converted to AS3 are part of my rotation for HTML<–>Flash content challenges for research right now. Usually most CMS in Flash has content loaded into the flash and then an alternate (sometimes similar) representation, here this is trying to merge the two which has it’s challenges.
EDIT: Title dyslexia
Using SharedObjects in Flash is very simple. Flash has SharedObjects that have been in the player since Flash6 when the introduction of Flash Communication Server which is now Flash Media Server which is releasing version 3 soon (also remote SharedObjects in Red5 is an open source RTMP media server that is based on Flash Media Server). So we can thank this release for SharedObjects, Camera objects, Audio, lots of the NetConnections, protocol enhancements and many other things. However to keep the tips simple we will just touch on the local usage and post a series of posts on these objects.
SharedObjects locally and remote have changed the way offline is thought about and are the backbone of many offline systems and prototypes. They have been influential in moving storage locally to remote in a lightweight AMF0 or AMF3 format.
SharedObject is in the flash.net namespace in AS3.
Here we show how to use the local version of a SharedObject to store data in the most simple form.
import flash.net.SharedObject; var so:SharedObject = SharedObject.getLocal("userData"); so.data.username= "user1377"; so.data.pwdhash= "[hash] or pwd"; so.flush(); // writes changes to disk
You can see this is extremely simple to store data.Here we show how to use the local version of a SharedObject to retrieve data in the most simple form.
import flash.net.SharedObject; var so:SharedObject = SharedObject.getLocal("userData"); var username:String = so.data.username; var pwdhash:String = so.data.pwdhash;
That is it! In the most basic form SharedObjects are more simple than cookies and also are quite nice living outside the bounds of the cookies folder. If a user deletes all cookies it will not delete the SharedObjects. To delete SharedObjects you need to roght click on the Flash player, go to Settings and delete the objects there.You can store any type of data Flash supports from objects to numbers to strings in the SharedObject data.
import flash.net.SharedObject; var so:SharedObject = SharedObject.getLocal("userData"); so.data.username= "user1377"; so.data.uid= new Number(1337); var obj:Object = new Object(); obj.prop = "value"; so.data.userobj= obj; so.flush(); // writes changes to disk
For large applications SharedObjects local are great because users can have their SharedObject space set to a high amount of space or unlmited for large offline type apps or more complex apps stored in a state object. It gets interesting when you pass this to the server in AMF or extremely compact AMF3 format to a remote stored object, via remoting, Shared Object events or any way you want to.We will be posting more on remote shared objects and some of the other tools such as Camera and Streams for AS3 over the coming weeks and deeper into the Sync Events for remote and local SOs.Sephiroth has a great Python tool to peer into the SOs on disk.
The first version of SharedObject Reader was written in python 2.2.
This new version is written in C# (C Sharp) as it’s now part of FlashDevelop editor.
Red5 also does this as well as many AMF kits.
Sync Events for SharedObject (as they change they launch a sync event)
Event object type: flash.events.SyncEvent
SyncEvent.type property = flash.events.SyncEvent.SYNC
Read more at adobe docs:
Sample from AS3 docs showing usage
package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.NetStatusEvent; import flash.net.SharedObject; import flash.net.SharedObjectFlushStatus; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFieldType; public class SharedObjectExample extends Sprite { private var mySo:SharedObject; public function SharedObjectExample() { buildUI(); saveBtn.addEventListener(MouseEvent.CLICK, saveValue); clearBtn.addEventListener(MouseEvent.CLICK, clearValue); mySo = SharedObject.getLocal("application-name"); output.appendText("SharedObject loaded...\n"); output.appendText("loaded value: " + mySo.data.savedValue + "\n\n"); } private function saveValue(event:MouseEvent):void { output.appendText("saving value...\n"); mySo.data.savedValue = input.text; var flushStatus:String = null; try { flushStatus = mySo.flush(10000); } catch (error:Error) { output.appendText("Error...Could not write SharedObject to disk\n"); } if (flushStatus != null) { switch (flushStatus) { case SharedObjectFlushStatus.PENDING: output.appendText("Requesting permission to save object...\n"); mySo.addEventListener(NetStatusEvent.NET_STATUS, onFlushStatus); break; case SharedObjectFlushStatus.FLUSHED: output.appendText("Value flushed to disk.\n"); break; } } output.appendText("\n"); } private function clearValue(event:MouseEvent):void { output.appendText("Cleared saved value...Reload SWF and the value should be \"undefined\".\n\n"); delete mySo.data.savedValue; } private function onFlushStatus(event:NetStatusEvent):void { output.appendText("User closed permission dialog...\n"); switch (event.info.code) { case "SharedObject.Flush.Success": output.appendText("User granted permission -- value saved.\n"); break; case "SharedObject.Flush.Failed": output.appendText("User denied permission -- value not saved.\n"); break; } output.appendText("\n"); mySo.removeEventListener(NetStatusEvent.NET_STATUS, onFlushStatus); } // UI elements private var inputLbl:TextField; private var input:TextField; private var output:TextField; private var saveBtn:Sprite; private var clearBtn:Sprite; private function buildUI():void { // input label inputLbl = new TextField(); addChild(inputLbl); inputLbl.x = 10; inputLbl.y = 10; inputLbl.text = "Value to save:"; // input TextField input = new TextField(); addChild(input); input.x = 80; input.y = 10; input.width = 100; input.height = 20; input.border = true; input.background = true; input.type = TextFieldType.INPUT; // output TextField output = new TextField(); addChild(output); output.x = 10; output.y = 35; output.width = 250; output.height = 250; output.multiline = true; output.wordWrap = true; output.border = true; output.background = true; // Save button saveBtn = new Sprite(); addChild(saveBtn); saveBtn.x = 190; saveBtn.y = 10; saveBtn.useHandCursor = true; saveBtn.graphics.lineStyle(1); saveBtn.graphics.beginFill(0xcccccc); saveBtn.graphics.drawRoundRect(0, 0, 30, 20, 5, 5); var saveLbl:TextField = new TextField(); saveBtn.addChild(saveLbl); saveLbl.text = "Save"; saveLbl.selectable = false; // Clear button clearBtn = new Sprite(); addChild(clearBtn); clearBtn.x = 230; clearBtn.y = 10; clearBtn.useHandCursor = true; clearBtn.graphics.lineStyle(1); clearBtn.graphics.beginFill(0xcccccc); clearBtn.graphics.drawRoundRect(0, 0, 30, 20, 5, 5); var clearLbl:TextField = new TextField(); clearBtn.addChild(clearLbl); clearLbl.text = "Clear"; clearLbl.selectable = false; } } }
Picnik is an excellent application that makes believers out of RIA skeptics made with Flash/Flex. Today Picnik is now integrated with Flickr bringing user friendly photoshop essentially to the masses.
This is a pretty interesting market direction as more photo companies like photobucket and flickr add to the competition for photo editing. As flash based uploads, photo editors, word processors, presentation creators, conference systems, office apps, planning apps and many others all over the web does this mean the services model is really here and RIA is not just a fad?
The model of software is changing, again. The one competitive edge that web applications, and specifically RIA apps have over desktop is that many desktop apps are bloated, have legacy evolution that caused heavy, busy interfaces and absolutely no abstraction of the possible user level in many cases. Web applications are for a broad audience so these applications will see many benefits in making simplified versions of applications for lower skilled users, and then for advanced users more features.
The model is entirely different. They also have the ability to embed in sites like flickr, photobucket, social networks, office product offerings, small business servers, etc. They could even compete on these sites. The install base will not be millions of client computers but networks and clusters of users at online places and services.
This was a dream with ASP applications and software as a service. The problem was before RIA some of the limits of the web were preventing web apps from overtaking and beating out the features of desktop apps. RIAs and the web, web services, user controlled environments are changing the way software is used. is We aren’t entirely there yet but RIAs are reviewing their schematics, late at night, and are slowly taking over the software world and changing the model. Like a ninja is Picnik.
Regarding Picnik, I can’t say enough about the simplicity, clean design that they have pulled off here. The website and application have an identical brand. The application is extremely responsive and acts like html sites would when it comes to text and forms. The integration of services, webcam, all filters in flash, on and on. They really have a great team and it seems like they are both a great product team but also have the right quality. The new market is extremely agile, the paradigm is shifting.









