<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Mike Chambers</title>
	
	<link>http://www.mikechambers.com/blog</link>
	<description>code = joy</description>
	<lastBuildDate>Sat, 07 Nov 2009 06:08:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/MikeChambers" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Moving a git repository subdirectory to its own repository</title>
		<link>http://feedproxy.google.com/~r/MikeChambers/~3/yC-70vHMNNk/</link>
		<comments>http://www.mikechambers.com/blog/2009/11/04/moving-a-git-repository-subdirectory-to-its-own-repository/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 17:48:40 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1885</guid>
		<description><![CDATA[I use Git and GitHub to manage all of my personal code projects. I have one large repository called projects, which is then broken into sub directories based on the main technology used for each project (i.e. Flash, JavaScript, iphone, etc&#8230;).
I am currently working on a Flash based iphone game code-named &#8220;pewpew&#8221;, which is maintained [...]]]></description>
			<content:encoded><![CDATA[<p>I use <a href="http://git-scm.com/">Git</a> and <a href="http://www.github.com">GitHub</a> to manage all of my personal code projects. I have one large repository called projects, which is then broken into sub directories based on the main technology used for each project (i.e. Flash, JavaScript, iphone, etc&#8230;).</p>
<p>I am currently working on a Flash based iphone game code-named &#8220;pewpew&#8221;, which is maintained within my projects repository. As I have begun to work on it more and more, I decided that I wanted to have pewpew in its own git repository. This will make it easier to track issues, as well as give me the option of open sourcing it and allow others to create and submit forks.<br />
<span id="more-1885"></span><br />
Initially it looked like the way to do this was to use <a href="http://www.kernel.org/pub/software/scm/git/docs/git-submodule.html">git submodules</a>. However that seemed to keep the code linked to the original repository, which I did not want. I could have simply copied the code over and then initialized it as a new repository, but I wanted to maintain the commit history. Finally, I came across an article at <a href="http://help.github.com/splitting-a-subpath-to-a-new-repo/">GitHub titled Splitting a subpath out into a new repo</a>. This does exactly what I needed (basically, create a new repository from a directory within an existing repository).</p>
<p>After following the steps in the article, I had to do one additional step before I could push the new repository to GitHub. I had to change the origin from the old repository url, to the new one. You can do this by changing the <em>[remote "origin"]</em> url property in the .git/config file to point to the new repository.</p>
<p>Anyways, this worked perfectly, and maintained the history. If anyone has any suggestions for other or better ways to accomplish this, please post it in the comments. Thanks for to everyone who had suggestions about this on twitter.</p>
<img src="http://feeds.feedburner.com/~r/MikeChambers/~4/yC-70vHMNNk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/11/04/moving-a-git-repository-subdirectory-to-its-own-repository/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.mikechambers.com/blog/2009/11/04/moving-a-git-repository-subdirectory-to-its-own-repository/</feedburner:origLink></item>
		<item>
		<title>FITC Edmonton Slides : Building iPhone applications with Flash CS5</title>
		<link>http://feedproxy.google.com/~r/MikeChambers/~3/w16oOwCOt7w/</link>
		<comments>http://www.mikechambers.com/blog/2009/10/20/fitc-edmonton-slides-building-iphone-applications-with-flash-cs5/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 18:36:10 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1878</guid>
		<description><![CDATA[Here are my slides from my FITC Edmonton talk titled &#8220;Building iPhone Applications with Flash CS5&#8220;.
You can download the slides from here.
Btw, really great conference and vibe, and the speaker list was simply amazing. Congrats to Shawn and the FITC crew for putting on another great event.
]]></description>
			<content:encoded><![CDATA[<p>Here are my slides from my <a href="http://www.fitc.ca/events/about/?event=99">FITC Edmonton</a> talk titled &#8220;<a href="/blog/files/presentations/fitc_edmonton_2009/flash_iphone.pdf">Building iPhone Applications with Flash CS5</a>&#8220;.</p>
<p>You can download the slides from <a href="/blog/files/presentations/fitc_edmonton_2009/flash_iphone.pdf">here</a>.</p>
<p>Btw, really great conference and vibe, and the speaker list was simply amazing. Congrats to Shawn and the <a href="http://www.fitc.ca/">FITC</a> crew for putting on another great event.</p>
<img src="http://feeds.feedburner.com/~r/MikeChambers/~4/w16oOwCOt7w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/10/20/fitc-edmonton-slides-building-iphone-applications-with-flash-cs5/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.mikechambers.com/blog/2009/10/20/fitc-edmonton-slides-building-iphone-applications-with-flash-cs5/</feedburner:origLink></item>
		<item>
		<title>Resources for Learning more about Flash to iPhone</title>
		<link>http://feedproxy.google.com/~r/MikeChambers/~3/El-RpOisdH4/</link>
		<comments>http://www.mikechambers.com/blog/2009/10/17/resources-for-learning-more-about-flash-to-iphone/#comments</comments>
		<pubDate>Sat, 17 Oct 2009 16:00:28 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1871</guid>
		<description><![CDATA[Below is a list of some of the best resources if you are interesting in getting a deeper understanding Adobe&#8217;s recent announcement that Flash CS5 will be able to output standalone applications for the iPhone.

Building Applications for the iPhone with Flash : My original blog post on the iPhone announcements.
Developer FAQ : Official FAQ which [...]]]></description>
			<content:encoded><![CDATA[<p>Below is a list of some of the best resources if you are interesting in getting a deeper understanding Adobe&#8217;s recent announcement that Flash CS5 will be able to output standalone applications for the iPhone.<br />
<span id="more-1871"></span><br />
<a href="http://www.mikechambers.com/blog/2009/10/05/building-applications-for-the-iphone-with-flash/">Building Applications for the iPhone with Flash</a> : My original blog post on the iPhone announcements.</p>
<p><a href="http://labs.adobe.com/wiki/index.php/Applications_for_iPhone">Developer FAQ</a> : Official FAQ which answers common questions about creating content for iPhone using Flash.</p>
<p><a href="http://www.mikechambers.com/blog/2009/10/12/why-you-should-not-care-about-building-apps-for-the-iphone-with-flash/">Why you should NOT care about building apps for the iPhone with Flash</a> : Blog post I made which puts the announcement into the context of the other Flash Player 10.1 announcements.</p>
<p><a href="http://www.insideria.com/2009/10/flash-and-iphone.html">Flash to iPhone</a> : Excellent article by Veronique Brossier (who was on the private pre-release) going into deep technical detail about creating applications for the iPhone using Flash.</p>
<p><a href="http://coderhump.com/archives/517">Flash on iPhone : My Experience</a> : Blog post by Ben Garney (of <a href="http://www.pushbuttonlabs.com">pushbuttonlabs</a>) talking about his experiences building the &#8220;Trading Stuff in Outer Space&#8221;" game for the iPhone using Flash.</p>
<p><a href="http://bit.ly/arnoiphone">Designing Flash Applications for the iPhone</a> : Max session from Arono Gourdol from the Adobe AIR team, talking about designing content for iPhone applications using Flash.</p>
<p><a href="http://www.bit.ly./iphoneopt">Optimizing Flash Content for iPhone Applications</a> Max session from Scott Petersen and Chris Brichford (two of the engineers who are working on the Flash to iPhone compiler technology), which goes in depth into how the toolchain works, as well as tips and tricks for optimizing content for the platfrom.</p>
<p><a href="http://max.adobe.com/online/session/362">Designing and Developing for the Multiscreen web</a> : Max session from Thibault Imbert (<a href="http://www.bytearray.org">bytearray.org</a>) talking about tip and tricks when developing for mobile devices.</p>
<img src="http://feeds.feedburner.com/~r/MikeChambers/~4/El-RpOisdH4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/10/17/resources-for-learning-more-about-flash-to-iphone/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.mikechambers.com/blog/2009/10/17/resources-for-learning-more-about-flash-to-iphone/</feedburner:origLink></item>
		<item>
		<title>Case Study : ActionScript 3 Performance Optimization</title>
		<link>http://feedproxy.google.com/~r/MikeChambers/~3/BDKSD-gHPq0/</link>
		<comments>http://www.mikechambers.com/blog/2009/10/13/case-study-actionscript-3-performance-optimization/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 17:27:49 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[actionscript3]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1865</guid>
		<description><![CDATA[Prompted by some of the work from Grant Skinner (in particular his FOTB 2009 session) and Thibault Imbert, I have been doing a lot of research lately into optimizing ActionScript 3 content. Not just how to make it run faster, but how to approach the process of optimization.
I am also starting to work on a [...]]]></description>
			<content:encoded><![CDATA[<p>Prompted by some of the work from <a href="http://www.gskinner.com/blog/">Grant Skinner</a> (in particular his <a href="http://gskinner.com/blog/archives/2004/06/conference_sess.html">FOTB 2009 session</a>) and <a href="http://www.bytearray.org/">Thibault Imbert</a>, I have been doing a lot of research lately into optimizing ActionScript 3 content. Not just how to make it run faster, but how to approach the process of optimization.</p>
<p>I am also starting to work on a small project which works with pixel data from images, and on which I anticipate performance might be an issue when working with larger images. I figured this would be a good opportunity to use some of the early code as a case study. I wanted to post the process and results here.<br />
<span id="more-1865"></span><br />
The task that I will focus on is grabbing a palette of 16 colors from an image, created by averaging the colors within that image. Upon searching on google, I found a <a href="http://blog.soulwire.co.uk/flash/actionscript-3/extract-average-colours-from-bitmapdata/">very good solution over at soulwire.co.uk</a>, which I will use as the base for creating the palette. I want to point out that the original code targeted Flash Player 9 (and thus couldn&#8217;t take advantage of some things such as Vectors), and already ran pretty blazingly fast.</p>
<p>I am using Grant Skinner&#8217;s <a href="http://www.gskinner.com/blog/archives/2009/04/as3_performance.html">performance test harness</a> to profile performance. Each test is run 50 times, and is tested in Flash Player MAC 10,0,32,18 (debug) in the browser. </p>
<p>You can download all of the code from <a href="/blog/files/examples/PixelSort.zip">here</a>.</p>
<p>First, here is the original test case, based on soulwire&#8217;s code:</p>
<div class="highlight">
<pre><span style="color: #408080; font-style: italic">/*</span>
<span style="color: #408080; font-style: italic">	Code adapted from:</span>
<span style="color: #408080; font-style: italic">	http://blog.soulwire.co.uk/flash/actionscript-3/colourutils-bitmapdata-extract-colour-palette/</span>
<span style="color: #408080; font-style: italic">*/</span>

package
{
	<span style="color: #008000; font-weight: bold">import</span> flash.display.Bitmap<span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.display.<span style="color: #008000">BitmapData</span><span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.display.Sprite<span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.events.Event<span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.geom.<span style="color: #008000">Rectangle</span><span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.geom.<span style="color: #008000">Point</span><span style="color: #666666">;</span>

	<span style="color: #008000; font-weight: bold">import</span> com.gskinner.utils.PerformanceTest<span style="color: #666666">;</span>

	<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">class</span> PixelSort <span style="color: #008000; font-weight: bold">extends</span> Sprite
	{

		[Embed(source<span style="color: #666666">=</span><span style="color: #BA2121">&quot;../graphics/image.jpg&quot;</span>)]
		<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">var</span> TestImage<span style="color: #666666">:</span>Class<span style="color: #666666">;</span>

		<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">function</span> PixelSort()
		{
			addEventListener(Event.ADDED_TO_STAGE<span style="color: #666666">,</span> onAddedToStage);
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> d<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span><span style="color: #666666">;</span>
		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> onAddedToStage(evet<span style="color: #666666">:</span>Event)<span style="color: #666666">:</span>void
		{
			removeEventListener(Event.ADDED_TO_STAGE<span style="color: #666666">,</span> onAddedToStage);

			<span style="color: #008000; font-weight: bold">var</span> b<span style="color: #666666">:</span>Bitmap <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> TestImage();

			d <span style="color: #666666">=</span> b.bitmapData<span style="color: #666666">;</span>

			<span style="color: #008000; font-weight: bold">var</span> perfTest<span style="color: #666666">:</span>PerformanceTest <span style="color: #666666">=</span> PerformanceTest.getInstance();
			perfTest.out <span style="color: #666666">=</span> <span style="color: #0000FF">trace</span><span style="color: #666666">;</span>
			perfTest.testFunction(run<span style="color: #666666">,</span> <span style="color: #666666">50,</span> <span style="color: #BA2121">&quot;averagecolors&quot;</span><span style="color: #666666">,</span> <span style="color: #BA2121">&quot;averagecolors&quot;</span>);
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> run()<span style="color: #666666">:</span>void
		{
			<span style="color: #008000; font-weight: bold">var</span> out<span style="color: #666666">:</span><span style="color: #008000">Array</span> <span style="color: #666666">=</span> averagecolors(d<span style="color: #666666">,</span> <span style="color: #666666">16</span>);
		}

		<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">function</span> averageColour( source<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span> )<span style="color: #666666">:</span>uint
		{
			<span style="color: #008000; font-weight: bold">var</span> red<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">var</span> green<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">var</span> blue<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> <span style="color: #666666">0;</span>

			<span style="color: #008000; font-weight: bold">var</span> count<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">var</span> pixel<span style="color: #666666">:</span><span style="color: #008000">Number</span><span style="color: #666666">;</span>

			<span style="color: #008000; font-weight: bold">for</span> (<span style="color: #008000; font-weight: bold">var</span> x<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span> x <span style="color: #666666">&lt;</span> source.width<span style="color: #666666">;</span> x<span style="color: #666666">++</span>)
			{
				<span style="color: #008000; font-weight: bold">for</span> (<span style="color: #008000; font-weight: bold">var</span> y<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span> y <span style="color: #666666">&lt;</span> source.height<span style="color: #666666">;</span> y<span style="color: #666666">++</span>)
				{
					pixel <span style="color: #666666">=</span> source.getPixel(x<span style="color: #666666">,</span> y);

					red <span style="color: #666666">+=</span> pixel <span style="color: #666666">&gt;&gt;</span> <span style="color: #666666">16</span> <span style="color: #666666">&amp;</span> <span style="color: #666666">0</span>xFF<span style="color: #666666">;</span>
					green <span style="color: #666666">+=</span> pixel <span style="color: #666666">&gt;&gt;</span> <span style="color: #666666">8</span> <span style="color: #666666">&amp;</span> <span style="color: #666666">0</span>xFF<span style="color: #666666">;</span>
					blue <span style="color: #666666">+=</span> pixel <span style="color: #666666">&amp;</span> <span style="color: #666666">0</span>xFF<span style="color: #666666">;</span>

					count<span style="color: #666666">++</span>
				}
			}

			red <span style="color: #666666">/=</span> count<span style="color: #666666">;</span>
			green <span style="color: #666666">/=</span> count<span style="color: #666666">;</span>
			blue <span style="color: #666666">/=</span> count<span style="color: #666666">;</span>

			<span style="color: #008000; font-weight: bold">return</span> red <span style="color: #666666">&lt;&lt;</span> <span style="color: #666666">16</span> <span style="color: #666666">|</span> green <span style="color: #666666">&lt;&lt;</span> <span style="color: #666666">8</span> <span style="color: #666666">|</span> blue<span style="color: #666666">;</span>
		}		

		<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">function</span> averagecolors( source<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span><span style="color: #666666">,</span> colors<span style="color: #666666">:</span>int )<span style="color: #666666">:</span><span style="color: #008000">Array</span>
		{
			<span style="color: #008000; font-weight: bold">var</span> averages<span style="color: #666666">:</span><span style="color: #008000">Array</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Array</span>();
			<span style="color: #008000; font-weight: bold">var</span> columns<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #008000">Math</span>.round( <span style="color: #008000">Math</span>.sqrt( colors ) );

			<span style="color: #008000; font-weight: bold">var</span> row<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">var</span> col<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>

			<span style="color: #008000; font-weight: bold">var</span> x<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">var</span> y<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>

			<span style="color: #008000; font-weight: bold">var</span> w<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #008000">Math</span>.round( source.width <span style="color: #666666">/</span> columns );
			<span style="color: #008000; font-weight: bold">var</span> h<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #008000">Math</span>.round( source.height <span style="color: #666666">/</span> columns );

			<span style="color: #008000; font-weight: bold">for</span> (<span style="color: #008000; font-weight: bold">var</span> i<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span> i <span style="color: #666666">&lt;</span> colors<span style="color: #666666">;</span> i<span style="color: #666666">++</span>)
			{
				<span style="color: #008000; font-weight: bold">var</span> rect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Rectangle</span>( x<span style="color: #666666">,</span> y<span style="color: #666666">,</span> w<span style="color: #666666">,</span> h );

				<span style="color: #008000; font-weight: bold">var</span> box<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>( w<span style="color: #666666">,</span> h<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">false</span> );
				box.copyPixels( source<span style="color: #666666">,</span> rect<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Point</span>() );

				averages.push( averageColour( box ) );
				box.dispose();

				col <span style="color: #666666">=</span> i <span style="color: #666666">%</span> columns<span style="color: #666666">;</span>

				x <span style="color: #666666">=</span> w <span style="color: #666666">*</span> col<span style="color: #666666">;</span>
				y <span style="color: #666666">=</span> h <span style="color: #666666">*</span> row<span style="color: #666666">;</span>

				<span style="color: #008000; font-weight: bold">if</span> ( col <span style="color: #666666">==</span> columns <span style="color: #666666">-</span> <span style="color: #666666">1</span> ) row<span style="color: #666666">++;</span>
			}

			<span style="color: #008000; font-weight: bold">return</span> averages<span style="color: #666666">;</span>
		}
	}
}
</pre>
</div>
<p>&nbsp;</p>
<p>And here is the initial performance test:</p>
<pre>––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
averagecolors (50 iterations)
Player version: MAC 10,0,32,18 (debug)
averagecolors
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
averagecolors                                              1264    25.28
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>First, considering what the code is doing, it is already pretty fast, taking only 25 ms to split the image into a grid, and loop through all of the pixels and averaging the values. However, there is probably some room for improvement, especially given that the original code targets Flash Player 9 and thus cant take care of Flash Player 10 optimizations such as using Vectors.</p>
<p>Now, the first thing I would normally do is to profile the SWF using the profiler in Flash Builder to find out where the most time is being sent. However, in this case, there are only two methods that do anything, <em>averageColors</em> and <em>averageColor</em>. <em>averageColors</em> is called once, while <em>averageColor</em> is called once for each swatch we want to create (in this case 16), and ends up looping over each pixel in the image (over those 16 calls). So these are the two areas we will focus on, with particular attention directed to <em>averageColor</em>.</p>
<p>The first thing I did was look at updating the content to Flash Player 10 by converting all of the Arrays to Vectors. I expected to get a decent boost from this, but the improvement was minimal.</p>
<p>Within the <em>averageColors</em> method, I looked at reusing the <em>Point</em>, <em>Rectangle</em> and <em>BitmapData</em> instances, instead of creating new ones on each iteration of the loop. Again, on the desktop this didn&#8217;t really make any difference. However, one thing to consider is that on a mobile device where memory allocation can be more expensive (and there is less RAM altogether), this change may have had a bigger impact (which I didnt test). This leads to an important point. It is important to test performance on the platforms which you are targeting, as some optimizations can have a different impact depending on where the content is running.</p>
<p>Next, I set the <em>averageColor</em> and <em>averageColors</em> methods as <em>final</em>, which allows them too be looked up at compile time (as opposed to runtime), this led to small improvement in performance, but again, not really anything significant.</p>
<p>At this point, I was getting a very slight performance improvement, but not really anything that mattered (basically, small enough to be insignificant),</p>
<pre>––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
averagecolors (50 iterations)
Player version: MAC 10,0,32,18 (debug)
averagecolors
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
averagecolors                                              1224    24.48
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––</pre>
<p>&nbsp;</p>
<p>Next, I moved on to the <em>averageColor</em> method, where I expected (and hoped) to have better results, as this is where the bulk of the work occurs.</p>
<p>First I converter some of the Numbers to ints and uints in places where Numbers were not needed. This led to a small improvement.</p>
<pre>––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
averagecolors (50 iterations)
Player version: MAC 10,0,32,18 (debug)
averagecolors
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
averagecolors                                              1190    23.80
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––</pre>
<p>&nbsp;</p>
<p>Next, I changed the <code>bitmapData.getPixel</code> call to use <code>bitmapData.getVector</code>. Doing this then allowed me to loop through the pixels using a single loop, instead of a nested double loop, and also eliminated a <em>getPixel</em> call for each pixel. I used a <em>for each</em> loop to loop through the pixel color values.</p>
<p>This provided another slight improvement (although not quite as much as I expected). We are now making some small gains.</p>
<pre>––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
averagecolors (50 iterations)
Player version: MAC 10,0,32,18 (debug)
averagecolors
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
averagecolors                                              1137    22.74
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––</pre>
<p>&nbsp;</p>
<p>Next, I decided to try a <em>for</em> loop, instead of a <em>for each</em> loop.</p>
<pre>––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
averagecolors (50 iterations)
Player version: MAC 10,0,32,18 (debug)
averagecolors
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
averagecolors                                               282     5.64
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––</pre>
<p>&nbsp;</p>
<p>Wow! As you can see, that makes a huge difference.</p>
<p>Finally, I explicitly cast <em>i</em> to an <em>int</em> when pulling the value from the Vector. This gave a small improvement, but again, nothing significant:</p>
<pre>––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
averagecolors (50 iterations)
Player version: MAC 10,0,32,18 (debug)
averagecolors
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
averagecolors                                               268     5.36
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––</pre>
<p>&nbsp;</p>
<p>I tried a couple of more optimizations in the method, around converting division operations to multiplication operation, and replacing <code>Math.round</code> calls but in this case it didnt make any difference.</p>
<p>I also looked at caching some constants used in some of the bitwise operations, changing</p>
<div class="highlight">
<pre>red <span style="color: #666666">+=</span> pixel <span style="color: #666666">&gt;&gt;</span> <span style="color: #666666">16</span> <span style="color: #666666">&amp;</span> <span style="color: #666666">0</span>xFF<span style="color: #666666">;</span>
green <span style="color: #666666">+=</span> pixel <span style="color: #666666">&gt;&gt;</span> <span style="color: #666666">8</span> <span style="color: #666666">&amp;</span> <span style="color: #666666">0</span>xFF<span style="color: #666666">;</span>
</pre>
</div>
<p>&nbsp;</p>
<p>to</p>
<div class="highlight">
<pre><span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> s16<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> <span style="color: #666666">16</span> <span style="color: #666666">&amp;</span> <span style="color: #666666">0</span>xFF<span style="color: #666666">;</span>
<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> s8<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> <span style="color: #666666">8</span> <span style="color: #666666">&amp;</span> <span style="color: #666666">0</span>xFF<span style="color: #666666">;</span>

red <span style="color: #666666">+=</span> pixel <span style="color: #666666">&gt;&gt;</span> s16<span style="color: #666666">;</span>
green <span style="color: #666666">+=</span> pixel <span style="color: #666666">&gt;&gt;</span> s8<span style="color: #666666">;</span>
</pre>
</div>
<p>&nbsp;</p>
<p>First, that optimization actually produces the wrong result (I had my operator precedence backwards). Second, it was actually slower:</p>
<pre>––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
averagecolors (50 iterations)
Player version: MAC 10,0,32,18 (debug)
averagecolors
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
averagecolors                                               349     6.98
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––</pre>
<p>&nbsp;</p>
<p>There are two lessons from this. First, make sure your optimizations produce the same results (ideally by creating and using unit tests). Second, bitwise operations are really, really fast. In this case, they are even faster than doing a variable lookup.</p>
<p>So, after going through the code, and applying a number of different optimizations, I was able to improve performance from an average of 25.28 ms, to 5.36 ms, an improvement of about 470%.</p>
<p>Here is the final code:</p>
<div class="highlight">
<pre><span style="color: #408080; font-style: italic">/*</span>
<span style="color: #408080; font-style: italic">	Code adapted from:</span>
<span style="color: #408080; font-style: italic">	http://blog.soulwire.co.uk/flash/actionscript-3/colourutils-bitmapdata-extract-colour-palette/</span>
<span style="color: #408080; font-style: italic">*/</span>

package
{
	<span style="color: #008000; font-weight: bold">import</span> flash.display.Bitmap<span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.display.<span style="color: #008000">BitmapData</span><span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.display.Sprite<span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.events.Event<span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.geom.<span style="color: #008000">Rectangle</span><span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.geom.<span style="color: #008000">Point</span><span style="color: #666666">;</span>

	<span style="color: #008000; font-weight: bold">import</span> com.gskinner.utils.PerformanceTest<span style="color: #666666">;</span>

	<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">class</span> PixelSort <span style="color: #008000; font-weight: bold">extends</span> Sprite
	{

		[Embed(source<span style="color: #666666">=</span><span style="color: #BA2121">&quot;../graphics/image.jpg&quot;</span>)]
		<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">var</span> TestImage<span style="color: #666666">:</span>Class<span style="color: #666666">;</span>

		<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">function</span> PixelSort()
		{
			addEventListener(Event.ADDED_TO_STAGE<span style="color: #666666">,</span> onAddedToStage);
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">var</span> d<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span><span style="color: #666666">;</span>
		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> onAddedToStage(evet<span style="color: #666666">:</span>Event)<span style="color: #666666">:</span>void
		{
			removeEventListener(Event.ADDED_TO_STAGE<span style="color: #666666">,</span> onAddedToStage);

			<span style="color: #008000; font-weight: bold">var</span> b<span style="color: #666666">:</span>Bitmap <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> TestImage();

			d <span style="color: #666666">=</span> b.bitmapData<span style="color: #666666">;</span>

			<span style="color: #008000; font-weight: bold">var</span> perfTest<span style="color: #666666">:</span>PerformanceTest <span style="color: #666666">=</span> PerformanceTest.getInstance();
			perfTest.out <span style="color: #666666">=</span> <span style="color: #0000FF">trace</span><span style="color: #666666">;</span>
			perfTest.testFunction(run<span style="color: #666666">,</span> <span style="color: #666666">50,</span> <span style="color: #BA2121">&quot;averagecolors&quot;</span><span style="color: #666666">,</span> <span style="color: #BA2121">&quot;averagecolors&quot;</span>);
		}

		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> run()<span style="color: #666666">:</span>void
		{
			<span style="color: #008000; font-weight: bold">var</span> out<span style="color: #666666">:</span>Vector.<span style="color: #666666">&lt;</span>uint<span style="color: #666666">&gt;</span> <span style="color: #666666">=</span> averagecolors(d<span style="color: #666666">,</span> <span style="color: #666666">16</span>);
		}		

		<span style="color: #008000; font-weight: bold">public</span> final <span style="color: #008000; font-weight: bold">function</span> averageColour( source<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span> )<span style="color: #666666">:</span>uint
		{
			<span style="color: #008000; font-weight: bold">var</span> red<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">var</span> green<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">var</span> blue<span style="color: #666666">:</span><span style="color: #008000">Number</span> <span style="color: #666666">=</span> <span style="color: #666666">0;</span>

			<span style="color: #008000; font-weight: bold">var</span> count<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">var</span> pixel<span style="color: #666666">:</span>uint<span style="color: #666666">;</span>

			<span style="color: #008000; font-weight: bold">var</span> pixels<span style="color: #666666">:</span>Vector.<span style="color: #666666">&lt;</span>uint<span style="color: #666666">&gt;</span> <span style="color: #666666">=</span> source.getVector(<span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Rectangle</span>(<span style="color: #666666">0,0,</span> source.width<span style="color: #666666">,</span> source.height));
			<span style="color: #008000; font-weight: bold">var</span> len<span style="color: #666666">:</span>int <span style="color: #666666">=</span> pixels.length<span style="color: #666666">;</span>

			<span style="color: #008000; font-weight: bold">for</span>(<span style="color: #008000; font-weight: bold">var</span> i<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span> i <span style="color: #666666">&lt;</span> len<span style="color: #666666">;</span> i<span style="color: #666666">++</span>)
			{
				pixel <span style="color: #666666">=</span> pixels[int(i)];

				red <span style="color: #666666">+=</span> pixel <span style="color: #666666">&gt;&gt;</span> <span style="color: #666666">16</span> <span style="color: #666666">&amp;</span> <span style="color: #666666">0</span>xFF<span style="color: #666666">;</span>
				green <span style="color: #666666">+=</span> pixel <span style="color: #666666">&gt;&gt;</span> <span style="color: #666666">8</span> <span style="color: #666666">&amp;</span> <span style="color: #666666">0</span>xFF<span style="color: #666666">;</span>
				blue <span style="color: #666666">+=</span> pixel <span style="color: #666666">&amp;</span> <span style="color: #666666">0</span>xFF<span style="color: #666666">;</span>

				count<span style="color: #666666">++;</span>
			}

			red <span style="color: #666666">/=</span> count<span style="color: #666666">;</span>
			green <span style="color: #666666">/=</span> count<span style="color: #666666">;</span>
			blue <span style="color: #666666">/=</span> count<span style="color: #666666">;</span>

			<span style="color: #008000; font-weight: bold">return</span> red <span style="color: #666666">&lt;&lt;</span> <span style="color: #666666">16</span> <span style="color: #666666">|</span> green <span style="color: #666666">&lt;&lt;</span> <span style="color: #666666">8</span> <span style="color: #666666">|</span> blue<span style="color: #666666">;</span>
		}		

		<span style="color: #008000; font-weight: bold">public</span> final <span style="color: #008000; font-weight: bold">function</span> averagecolors( source<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span><span style="color: #666666">,</span> colors<span style="color: #666666">:</span>int )<span style="color: #666666">:</span>Vector.<span style="color: #666666">&lt;</span>uint<span style="color: #666666">&gt;</span>
		{

			<span style="color: #008000; font-weight: bold">var</span> averages<span style="color: #666666">:</span>Vector.<span style="color: #666666">&lt;</span>uint<span style="color: #666666">&gt;</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> Vector.<span style="color: #666666">&lt;</span>uint<span style="color: #666666">&gt;</span>(colors<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">false</span>);
			<span style="color: #008000; font-weight: bold">var</span> columns<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #008000">Math</span>.round( <span style="color: #008000">Math</span>.sqrt( colors ) );

			<span style="color: #008000; font-weight: bold">var</span> row<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">var</span> col<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>

			<span style="color: #008000; font-weight: bold">var</span> x<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">var</span> y<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>

			<span style="color: #008000; font-weight: bold">var</span> w<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #008000">Math</span>.round( source.width <span style="color: #666666">/</span> columns );
			<span style="color: #008000; font-weight: bold">var</span> h<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #008000">Math</span>.round( source.height <span style="color: #666666">/</span> columns );

			<span style="color: #008000; font-weight: bold">var</span> p<span style="color: #666666">:</span><span style="color: #008000">Point</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Point</span>();
			<span style="color: #008000; font-weight: bold">var</span> rect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Rectangle</span>(<span style="color: #666666">0,0,0,0</span>);
			<span style="color: #008000; font-weight: bold">var</span> box<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>( w<span style="color: #666666">,</span> h<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">false</span> );

			<span style="color: #008000; font-weight: bold">for</span> (<span style="color: #008000; font-weight: bold">var</span> i<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span> i <span style="color: #666666">&lt;</span> colors<span style="color: #666666">;</span> i<span style="color: #666666">++</span>)
			{
				rect.x <span style="color: #666666">=</span> x<span style="color: #666666">;</span>
				rect.y <span style="color: #666666">=</span> y<span style="color: #666666">;</span>
				rect.width <span style="color: #666666">=</span> w<span style="color: #666666">;</span>
				rect.height <span style="color: #666666">=</span> h<span style="color: #666666">;</span>

				box.copyPixels( source<span style="color: #666666">,</span> rect<span style="color: #666666">,</span> p );

				averages[i] <span style="color: #666666">=</span>  averageColour( box );

				col <span style="color: #666666">=</span> i <span style="color: #666666">%</span> columns<span style="color: #666666">;</span>

				x <span style="color: #666666">=</span> w <span style="color: #666666">*</span> col<span style="color: #666666">;</span>
				y <span style="color: #666666">=</span> h <span style="color: #666666">*</span> row<span style="color: #666666">;</span>

				<span style="color: #008000; font-weight: bold">if</span> ( col <span style="color: #666666">==</span> columns <span style="color: #666666">-</span> <span style="color: #666666">1</span> )
				{
					row<span style="color: #666666">++;</span>
				}
			}
			box.dispose();
			<span style="color: #008000; font-weight: bold">return</span> averages<span style="color: #666666">;</span>
		}
	}
}
</pre>
</div>
<p>&nbsp;</p>
<p><strong>Lessons learned</strong></p>
<p><strong>Profile content to isolate bottlenecks</strong> : I skipped that step in this case since my code consisted of only two methods, but even in that case, the most significant improvement came from a single optimization. Profile so you know where to focus your efforts.</p>
<p><strong>Test and profile all optimizations</strong> : Make sure to test performance after each optimization, as optimizations do not always have the desired effect.</p>
<p><strong>Test on target devices and platforms</strong> : Optimizations can have a different impact on where they are run. This includes browser, platform and device, as well as player type (debug vs release). For example, when testing directly from Flash Authoring, results where significantly slower than when testing in the browser. </p>
<p><strong>Test the results of the optimizations</strong> : Make sure that your optimizations do not break your code or content. The best way to do this is by using unit tests and running them after each optimization.</p>
<p>There is still some potential for optimization. In particular, since the code is essentially looping over all of the pixels of a bitmap and then doing some math operations on their values, this could be a good candidate for porting to PixelBender.</p>
<p>If you have any additional optimizations, questions or suggestions, post them in the comments.</p>
<p>Also, make sure to check out <a href="http://blog.soulwire.co.uk/">soulwire&#8217;s blog</a>, as he is doing some very cool stuff with ActionScript 3 and Flash.</p>
<img src="http://feeds.feedburner.com/~r/MikeChambers/~4/BDKSD-gHPq0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/10/13/case-study-actionscript-3-performance-optimization/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		<feedburner:origLink>http://www.mikechambers.com/blog/2009/10/13/case-study-actionscript-3-performance-optimization/</feedburner:origLink></item>
		<item>
		<title>Why you should NOT care about building apps for the iPhone with Flash</title>
		<link>http://feedproxy.google.com/~r/MikeChambers/~3/lvM2jlzT9to/</link>
		<comments>http://www.mikechambers.com/blog/2009/10/12/why-you-should-not-care-about-building-apps-for-the-iphone-with-flash/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 18:12:26 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[10.1]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[flashplayer]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[max]]></category>
		<category><![CDATA[palmpre]]></category>
		<category><![CDATA[rim]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1857</guid>
		<description><![CDATA[The news from Adobe MAX 2009 that probably generated the most buzz and discussion online was the announcement that Flash CS5 will have support for outputting applications for the iPhone. While I am really excited about the news, and the work we are doing around the iPhone, I am here to tell you that you [...]]]></description>
			<content:encoded><![CDATA[<p>The news from Adobe MAX 2009 that probably generated the most buzz and discussion online was the announcement that <a href="http://www.mikechambers.com/blog/2009/10/05/building-applications-for-the-iphone-with-flash/">Flash CS5 will have support for outputting applications for the iPhone</a>. While I am really excited about the news, and the work we are doing around the iPhone, I am here to tell you that you should not care about it.<br />
<span id="more-1857"></span><br />
Let me repeat that:</p>
<p>You should NOT care about using Flash to build applications for the iPhone.</p>
<p>Hear me out on this. One of the major advantages of using Flash has always been that you can create your content, and then be confident that it will run consistently across different platforms and browsers. However, in the past, if you wanted to deploy to mobile platforms or devices, you would have to target a different player (most likely based on Flash Lite), which lagged behind the capabilities of the desktop player. However, the fragmentation between desktop and mobile players is about to change.</p>
<p>I think the biggest news out of Max last week was not the Flash applications for iPhone announcements, but rather the <a href="http://labs.adobe.com/technologies/flashplayer10/">unveiling of Flash Player 10.1</a>. Not only will Flash Player 10.1 run across desktop operating systems and browsers, but it will also be available on the newest generation of smart phones. This includes Palm Pre, as well as Android and <a href="http://www.adobe.com/aboutadobe/pressroom/pressreleases/200910/100509RIMjoinsOSP.html">RIM</a> based devices. Furthermore, the iPhone work, as well as Adobe AIR 2.0 are both also based on Flash Player 10.1.</p>
<p>Thus, not only will you be able to create content and target multiple browsers and operating systems, but you will also be able to target mobile devices, as well as desktops.</p>
<p>Now, it is important to remember that devices, such as the Palm Pre and iPhone have significantly slower processors and less memory, as well as smaller screens than desktop machines. However, if you design and develop with these limitations in mind, then you will be able to leverage you content anywhere that Flash Player 10.1 is available.</p>
<p>Furthermore, if you are leveraging functionality that is only available on a subset of devices, then of course, your content can only leverage that functionality on devices where it is supported. This is the same as on the desktop when using APIs to access the user&#8217;s microphone and webcam. If the target platform supports the functionality then you can use the APIs to access that functionality. (The Flash Player includes APIs to check at runtime if specific functionality is supported on any particular target platform).</p>
<p>The important thing is that the Flash Player exposes the APIs across platforms in a consistent manner. So, for example, if you want to use multitouch functionality in Flash Player 10.1, then you will use the same APIs regardless of whether your content is running on the desktop, in a browser, on the iPhone, the Palm Pre, etc&#8230;</p>
<p><a href="http://www.flickr.com/photos/mikechambers/4005016921/" title="PewPew by mike.chambers, on Flickr"><img src="http://farm3.static.flickr.com/2571/4005016921_aa3d6d3472_m.jpg" width="160" height="240" alt="PewPew" align="right" /></a>For the past couple of months, I have been working on a gamed called &#8220;Pew Pew&#8221;. I originally developed it by targeting the browser, but knowing that I wanted to deploy it to the iPhone, payed attention to performance, and sized the content, and designed the user interactions appropriately. Once the iPhone work was at a point internally that I could deploy content to it, I was able to run my content on the device with no changes at all. Now, I did have to do some additional code optimizations to bring the frame-rate up (something which benefitted the game on the desktop as well), but once I did these, the SWF for my game was able to run on both in the browser on my desktop and as a standalone iPhone application. Indeed, the team working on Flash Player 10.1 for Android asked if I could send them the SWF, and it ran on that device as well with no modifications. This was possible because Flash Player 10.1 allowed me to target the capabilities that my game needed, as opposed to targeting a particular device.</p>
<p>So, to summarize, when developing content targeted at Flash Player 10.1, you should think in terms of the capabilities of the platform, and not get hung up on a particular device or browser.</p>
<p>Creating applications for the iPhone is great. But creating content for the iPhone, and having the option to deploy it on an Android, RIM or Palm Pre device, in a browser on Mac, Windows, Linux and Solaris, and being able to deploy to the Mac, Windows and Linux desktops via Adobe AIR 2.0 is even better.</p>
<img src="http://feeds.feedburner.com/~r/MikeChambers/~4/lvM2jlzT9to" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/10/12/why-you-should-not-care-about-building-apps-for-the-iphone-with-flash/feed/</wfw:commentRss>
		<slash:comments>49</slash:comments>
		<feedburner:origLink>http://www.mikechambers.com/blog/2009/10/12/why-you-should-not-care-about-building-apps-for-the-iphone-with-flash/</feedburner:origLink></item>
		<item>
		<title>Max Session Update : Flash for iPhone Q and A</title>
		<link>http://feedproxy.google.com/~r/MikeChambers/~3/5qWJAOosqw8/</link>
		<comments>http://www.mikechambers.com/blog/2009/10/05/max-session-update-flash-for-iphone-q-and-a/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 20:48:13 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1852</guid>
		<description><![CDATA[Just a quick note, but my Max session for Wednesday morning, at ( 9:30 AM) titled &#8220;Secret Session : Flash&#8221; is now an open Q and A with the Flash Player and AIR teams to talk about creating applications for the iPhone with Flash.
]]></description>
			<content:encoded><![CDATA[<p>Just a quick note, but my Max session for Wednesday morning, at ( 9:30 AM) titled &#8220;Secret Session : Flash&#8221; is now an open Q and A with the Flash Player and AIR teams to talk about creating applications for the iPhone with Flash.</p>
<img src="http://feeds.feedburner.com/~r/MikeChambers/~4/5qWJAOosqw8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/10/05/max-session-update-flash-for-iphone-q-and-a/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://www.mikechambers.com/blog/2009/10/05/max-session-update-flash-for-iphone-q-and-a/</feedburner:origLink></item>
		<item>
		<title>Building Applications for the iPhone with Flash</title>
		<link>http://feedproxy.google.com/~r/MikeChambers/~3/IRvHxW8Zp-w/</link>
		<comments>http://www.mikechambers.com/blog/2009/10/05/building-applications-for-the-iphone-with-flash/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 18:24:31 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1849</guid>
		<description><![CDATA[This morning during the day 1 keynote at Adobe Max 2009, Adobe announced that the next version of Adobe Flash (Flash Professional CS5) will include support for creating stand-alone applications for the Apple iPhone and iPod Touch. As you can imagine, this is something that we are really excited about, and we expect there to [...]]]></description>
			<content:encoded><![CDATA[<p>This morning during the day 1 keynote at <a href="http://max.adobe.com/">Adobe Max 2009</a>, Adobe announced that the next version of Adobe Flash (Flash Professional CS5) will include support for creating stand-alone applications for the Apple iPhone and iPod Touch. As you can imagine, this is something that we are really excited about, and we expect there to be a lot of questions. This post should address some of those questions, and point to additional resources with more information.</p>
<p>So, what exactly did we announce?<br />
<span id="more-1849"></span><br />
The next version of Flash Authoring will enable developers to create stand-alone iPhone applications using Flash technologies (including ActionScript 3). These applications are just like any other iPhone application and can be distributed via the Apple iTunes Application store. Indeed, there are already a <a href="http://labs.adobe.com/wiki/index.php/Applications_for_iPhone:Developer_FAQ#Are_there_currently_any_applications_on_the_iTunes_App_Store_created_with_Flash.3F">number of applications</a> created with Flash on the store today.</p>
<p>One thing I want to stress is that this is for standalone applications, and is not the Flash Player for mobile Safari (which is something we continue to work on). The end result is a native iPhone application, and not a SWF that runs in the browser. We compile the SWF to a native application using <a href="http://www.adobe.com/devnet/logged_in/abansod_iphone.html">LLVM</a>. There is no requirement for the Flash Player / Adobe AIR Runtime to be installed on the device or included in the application. The end result is a native iPhone application.</p>
<p>Currently, this project is in private beta, and we plan to release a public beta of Flash CS5 with support for building iPhone applications before the end of this year. We are not accepting any new people for the private beta, but you can <a href="http://www.adobe.com/go/flashprobetanotify">sign up to be notified</a> when the public beta is available.</p>
<p>We have posted a <a href="http://labs.adobe.com/wiki/index.php/Applications_for_iPhone:Developer_FAQ">developer FAQ</a> on labs, which addresses a lot of the questions we expect you will have (we will continue to update this as necessary). The FAQ also includes some information that will be helpful if you want to start working on some content in anticipation of the public beta.</p>
<p>One thing that I really want to stress though, is that developing for the iPhone is mobile / device development. The iPhone has a significantly slower processor and less memory than what can be found in a typical desktop computer. As such, existing content may need to be optimized for performance, and / or user interactions (given the smaller screen and different UI metaphors). So, design and develop content with these limitations and differences in mind. Fortunately, we have done some things in the compiler, including enabling support for hardware accelerated rendering, to help with performance. Expect more information on this, and other optimization strategies once the public beta is available.</p>
<p>I am sure there are a lot of questions. As I mentioned above, we have created a <a href="http://labs.adobe.com/wiki/index.php/Applications_for_iPhone:Developer_FAQ">developer FAQ</a> that should address a lot of the most common questions. We have also created a <a href="http://forums.adobe.com/community/labs/flashcs5/appsfor_iphone">forum</a> for discussion of the announcements and technologies. Please feel free to also post any questions in the comments here.</p>
<p>Here are some additional resources:</p>
<ul>
<li><a href="http://labs.adobe.com/technologies/flashcs5/appsfor_iphone/">Flash Applications for iPhone on Labs</a></li>
<li><a href="http://www.adobe.com/devnet/logged_in/abansod_iphone.html">Developing for the Apple iPhone using Flash</a></li>
<li><a href="http://labs.adobe.com/wiki/index.php/Applications_for_iPhone:Developer_FAQ">Developer FAQ</a></li>
<li><a href="http://forums.adobe.com/community/labs/flashcs5/appsfor_iphone">iPhone forum</a></li>
</ul>
<p>Finally, if you are attending Max, we have a number of sessions which will cover building iPhone applications using Flash. I will make another post with information on those shortly (my session will be a general Q &#038; A session on building iPhone applications with Flash).</p>
<img src="http://feeds.feedburner.com/~r/MikeChambers/~4/IRvHxW8Zp-w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/10/05/building-applications-for-the-iphone-with-flash/feed/</wfw:commentRss>
		<slash:comments>84</slash:comments>
		<feedburner:origLink>http://www.mikechambers.com/blog/2009/10/05/building-applications-for-the-iphone-with-flash/</feedburner:origLink></item>
		<item>
		<title>Pixel Mesh on Why Max</title>
		<link>http://feedproxy.google.com/~r/MikeChambers/~3/z8Rfi1_aF0w/</link>
		<comments>http://www.mikechambers.com/blog/2009/09/29/pixel-mesh-on-why-max/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 18:20:10 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1841</guid>
		<description><![CDATA[Video after the break:


This was built using the new Microphone Access APIs coming in the next version of Adobe AIR (code named &#8220;Athena&#8221;). Some more info here.
Lots of info on Athena and other new technologies at Adobe Max 2009.
Pixel Mesh graphics created by eboy.
]]></description>
			<content:encoded><![CDATA[<p>Video after the break:<br />
<span id="more-1841"></span><br />
<object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/iIbTGtfNfZw&#038;hl=en&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/iIbTGtfNfZw&#038;hl=en&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></p>
<p>This was built using the new Microphone Access APIs coming in the next version of Adobe AIR (code named &#8220;Athena&#8221;). Some more info <a href="http://www.mikechambers.com/blog/2009/09/22/fotb-slides-advanced-desktop-development-with-adobe-air/">here</a>.</p>
<p>Lots of info on Athena and other new technologies at <a href="http://max.adobe.com/">Adobe Max 2009</a>.</p>
<p>Pixel Mesh graphics created by <a href="http://hello.eboy.com/eboy/">eboy</a>.</p>
<img src="http://feeds.feedburner.com/~r/MikeChambers/~4/z8Rfi1_aF0w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/09/29/pixel-mesh-on-why-max/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.mikechambers.com/blog/2009/09/29/pixel-mesh-on-why-max/</feedburner:origLink></item>
		<item>
		<title>FOTB Slides : Advanced Desktop Development with Adobe AIR</title>
		<link>http://feedproxy.google.com/~r/MikeChambers/~3/SwMTBfdVHG0/</link>
		<comments>http://www.mikechambers.com/blog/2009/09/22/fotb-slides-advanced-desktop-development-with-adobe-air/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 21:56:27 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1835</guid>
		<description><![CDATA[I am in Brighton for Flash on the Beach 2009 (amazing conference as usual). I gave a presentation on Adobe AIR yesterday, titled &#8220;Advanced Desktop Development with Adobe AIR&#8220;, which went well. I covered how to accomplish and approach a number of development tasks when working with AIR, and also talked about a couple of [...]]]></description>
			<content:encoded><![CDATA[<p>I am in Brighton for <a href="http://www.flashonthebeach.com/">Flash on the Beach 2009</a> (amazing conference as usual). I gave a presentation on Adobe AIR yesterday, titled &#8220;<a href="/blog/files/presentations/fotb2009/advanced_desktop_development.pdf">Advanced Desktop Development with Adobe AIR</a>&#8220;, which went well. I covered how to accomplish and approach a number of development tasks when working with AIR, and also talked about a couple of new features that we are working on.</p>
<p>I have posted the slides for the session, which you can grab from <a href="/blog/files/presentations/fotb2009/advanced_desktop_development.pdf">here</a>.</p>
<p>You can find most of the libraries and code I discussed on the<a href="http://code.google.com/p/as3corelib/"> as3corelib library page</a> (look in the com.adobe.air package).</p>
<p>Marc Hibbins has notes on the session <a href="http://blog.marchibbins.com/2009/09/22/the-beach/">here</a>.</p>
<img src="http://feeds.feedburner.com/~r/MikeChambers/~4/SwMTBfdVHG0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/09/22/fotb-slides-advanced-desktop-development-with-adobe-air/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		<feedburner:origLink>http://www.mikechambers.com/blog/2009/09/22/fotb-slides-advanced-desktop-development-with-adobe-air/</feedburner:origLink></item>
		<item>
		<title>Parsing and displaying BMP files via ActionScript</title>
		<link>http://feedproxy.google.com/~r/MikeChambers/~3/CW2dIG9piF0/</link>
		<comments>http://www.mikechambers.com/blog/2009/09/17/parsing-and-displaying-bmp-files-via-actionscript/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 21:32:20 +0000</pubDate>
		<dc:creator>mikechambers</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[bytearray]]></category>

		<guid isPermaLink="false">http://www.mikechambers.com/blog/?p=1830</guid>
		<description><![CDATA[I dont have a formal computer science training / education, so I never got the chance to learn about working with low level data structures (bits and bytes). I have wanted to learn this for some time, but had difficulty finding resources for it which didnt assume I had a computer science degree.
Well, yesterday, FITC [...]]]></description>
			<content:encoded><![CDATA[<p>I dont have a formal computer science training / education, so I never got the chance to learn about working with low level data structures (bits and bytes). I have wanted to learn this for some time, but had difficulty finding resources for it which didnt assume I had a computer science degree.</p>
<p>Well, yesterday, FITC posted <a href="http://www.fitc.ca/media/">all of the video sessions from FITC Toronto</a>, and I spent some time watching Lee Brimelow&#8217;s presentation on working with ByteArrays. It is a really great session, that provides a clear and solid foundation and understanding of working with ByteArrays and bits and bytes.</p>
<p>Anyways, after watching Lee&#8217;s session, it all finally clicked for me, and I spent some time last night putting together a simple parser that would dynamically load and display a <a href="http://en.wikipedia.org/wiki/BMP%5Ffile%5Fformat">24Bit BMP image file</a> within Flash.<br />
<span id="more-1830"></span><br />
I wanted to post the code below, along with complete comments, in order to provide a simple, real world example for anyone else interested in learning how to work with lower level file formats. </p>
<p>The code requires Adobe AIR (so I can load the BMP directly). In order to convert to the Flash Player in the browser, just replace the File loading with FileReference.browse.</p>
<div class="highlight">
<pre>package
{
	<span style="color: #008000; font-weight: bold">import</span> flash.filesystem.File<span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.filesystem.FileStream<span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.filesystem.FileMode<span style="color: #666666">;</span>

	<span style="color: #008000; font-weight: bold">import</span> flash.display.Sprite<span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.display.<span style="color: #008000">BitmapData</span><span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.display.Bitmap<span style="color: #666666">;</span>
	<span style="color: #008000; font-weight: bold">import</span> flash.utils.Endian<span style="color: #666666">;</span>

	<span style="color: #008000; font-weight: bold">import</span> flash.geom.<span style="color: #008000">Rectangle</span><span style="color: #666666">;</span>

	[SWF(width<span style="color: #666666">=</span><span style="color: #BA2121">&#39;550&#39;</span><span style="color: #666666">,</span> height<span style="color: #666666">=</span><span style="color: #BA2121">&#39;400&#39;</span><span style="color: #666666">,</span> backgroundColor<span style="color: #666666">=</span><span style="color: #BA2121">&#39;#FFFFFF&#39;</span><span style="color: #666666">,</span> frameRate<span style="color: #666666">=</span><span style="color: #BA2121">&#39;12&#39;</span>)]
	<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">class</span> BMPViewer <span style="color: #008000; font-weight: bold">extends</span> Sprite
	{
		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">static</span> const MAGIC_NUMBER<span style="color: #666666">:</span><span style="color: #008000">String</span> <span style="color: #666666">=</span> <span style="color: #BA2121">&quot;BM&quot;</span><span style="color: #666666">;</span>
		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">static</span> const BMP_DATA_OFFSET_POSITION<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0</span>xA<span style="color: #666666">;</span>
		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">static</span> const WIDTH_POSITION<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0x12;</span>
		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">static</span> const HEIGHT_POSITION<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0x16;</span>

		<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">function</span> BMPViewer()
		{
			loadBMP();
			<span style="color: #008000; font-weight: bold">super</span>();
		}

		<span style="color: #408080; font-style: italic">/*</span>
<span style="color: #408080; font-style: italic">			Loads and reads a 24 Bit bitmap file.</span>
<span style="color: #408080; font-style: italic">			</span>
<span style="color: #408080; font-style: italic">			Based on BMP info from:</span>
<span style="color: #408080; font-style: italic">			http://en.wikipedia.org/wiki/BMP%5Ffile%5Fformat</span>
<span style="color: #408080; font-style: italic">		*/</span>
		<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">function</span> loadBMP()<span style="color: #666666">:</span>void
		{
			<span style="color: #408080; font-style: italic">//Load BMP. This requires AIR.</span>
			<span style="color: #408080; font-style: italic">//Use FileReference.browse for</span>
			<span style="color: #408080; font-style: italic">//Flash Player</span>
			<span style="color: #008000; font-weight: bold">var</span> bmpFile<span style="color: #666666">:</span>File <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> File(<span style="color: #BA2121">&quot;app:/image.bmp&quot;</span>);
			<span style="color: #008000; font-weight: bold">var</span> fs<span style="color: #666666">:</span>FileStream <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> FileStream();

			<span style="color: #408080; font-style: italic">//BMP files are Little Endian, which means their</span>
			<span style="color: #408080; font-style: italic">//least significant byte is first (right to left)</span>
			fs.endian <span style="color: #666666">=</span> Endian.LITTLE_ENDIAN<span style="color: #666666">;</span>

			<span style="color: #408080; font-style: italic">//open the file in READ mode</span>
			fs.open(bmpFile<span style="color: #666666">,</span> FileMode.READ);

			<span style="color: #408080; font-style: italic">//check the first two bytes to make sure</span>
			<span style="color: #408080; font-style: italic">//it is a valid BMP file</span>
			<span style="color: #008000; font-weight: bold">if</span>(fs.readUTFBytes(<span style="color: #666666">2</span>) <span style="color: #666666">!=</span> MAGIC_NUMBER)
			{
				<span style="color: #0000FF">trace</span>(<span style="color: #BA2121">&quot;FAIL : NOT A BMP FILE&quot;</span>);

				<span style="color: #408080; font-style: italic">//not a BMP file, close steam</span>
				<span style="color: #408080; font-style: italic">//and exit</span>
				fs.close();
				<span style="color: #008000; font-weight: bold">return</span><span style="color: #666666">;</span>
			}

			<span style="color: #408080; font-style: italic">//note, we could also grab the length from the </span>
			<span style="color: #408080; font-style: italic">//header and make sure the file was the correct</span>
			<span style="color: #408080; font-style: italic">//length</span>

			<span style="color: #408080; font-style: italic">//change the cursors position to the point</span>
			<span style="color: #408080; font-style: italic">//in the header that contains the value / offset</span>
			<span style="color: #408080; font-style: italic">//of where the actual bitmap data begins</span>
			<span style="color: #408080; font-style: italic">//read in the 4 Bytes that contain the value</span>
			fs.position <span style="color: #666666">=</span> BMP_DATA_OFFSET_POSITION<span style="color: #666666">;</span>
			<span style="color: #008000; font-weight: bold">var</span> dataPosition<span style="color: #666666">:</span>int <span style="color: #666666">=</span> fs.readInt();

			<span style="color: #408080; font-style: italic">//set cursor position to where the BMP</span>
			<span style="color: #408080; font-style: italic">//width is stored</span>
			fs.position <span style="color: #666666">=</span> WIDTH_POSITION<span style="color: #666666">;</span>

			<span style="color: #408080; font-style: italic">//read in the 4 Bytes that contain the width</span>
			<span style="color: #008000; font-weight: bold">var</span> bmpWidth<span style="color: #666666">:</span>int <span style="color: #666666">=</span> fs.readInt();

			<span style="color: #408080; font-style: italic">//read in the 4 Bytes that contain the height</span>
			<span style="color: #008000; font-weight: bold">var</span> bmpHeight<span style="color: #666666">:</span>int <span style="color: #666666">=</span> fs.readInt();

			<span style="color: #408080; font-style: italic">//set cursor to where the BMP pixel data begins</span>
			fs.position <span style="color: #666666">=</span> dataPosition<span style="color: #666666">;</span>

			<span style="color: #008000; font-weight: bold">var</span> row<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">var</span> column<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>

			<span style="color: #408080; font-style: italic">//every row length in a BMP file must bee a multiple</span>
			<span style="color: #408080; font-style: italic">//of 4 (see the spec). So, we need to determine how much</span>
			<span style="color: #408080; font-style: italic">//padding we need to add at the end of each line. </span>
			<span style="color: #008000; font-weight: bold">var</span> padding<span style="color: #666666">:</span>int <span style="color: #666666">=</span> (bmpWidth <span style="color: #666666">%</span> <span style="color: #666666">4</span>);

			<span style="color: #408080; font-style: italic">//create a fixed length Vector to store the pixel</span>
			<span style="color: #408080; font-style: italic">//values as we read them.</span>
			<span style="color: #008000; font-weight: bold">var</span> pixels<span style="color: #666666">:</span>Vector.<span style="color: #666666">&lt;</span>uint<span style="color: #666666">&gt;</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> Vector.<span style="color: #666666">&lt;</span>uint<span style="color: #666666">&gt;</span>(bmpWidth <span style="color: #666666">*</span> bmpHeight<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">true</span>);

			<span style="color: #408080; font-style: italic">//loop through data (rows and columns)</span>
			<span style="color: #408080; font-style: italic">//note that data stored in BMP is backwards to Flash and is</span>
			<span style="color: #408080; font-style: italic">//stored from bottom row up, not top row down.</span>
			<span style="color: #408080; font-style: italic">//So we have to loop backwards</span>
			<span style="color: #008000; font-weight: bold">var</span> counter<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span>
			<span style="color: #008000; font-weight: bold">for</span>(<span style="color: #008000; font-weight: bold">var</span> i<span style="color: #666666">:</span>int <span style="color: #666666">=</span> bmpHeight<span style="color: #666666">;</span> i <span style="color: #666666">&gt;</span> <span style="color: #666666">0;</span> i<span style="color: #666666">--</span>)
			{
				<span style="color: #008000; font-weight: bold">for</span>(<span style="color: #008000; font-weight: bold">var</span> k<span style="color: #666666">:</span>int <span style="color: #666666">=</span> <span style="color: #666666">0;</span> k <span style="color: #666666">&lt;</span> bmpWidth<span style="color: #666666">;</span> k<span style="color: #666666">++</span>)
				{

					<span style="color: #008000; font-weight: bold">var</span> position<span style="color: #666666">:</span>int <span style="color: #666666">=</span> ((i <span style="color: #666666">-</span> <span style="color: #666666">1</span>) <span style="color: #666666">*</span> bmpWidth) <span style="color: #666666">+</span> k<span style="color: #666666">;</span>
					<span style="color: #408080; font-style: italic">/*</span>
<span style="color: #408080; font-style: italic">						This is the original code that I had which works fine</span>
<span style="color: #408080; font-style: italic">						but is not as effecient as what I have now.</span>
<span style="color: #408080; font-style: italic">						</span>
<span style="color: #408080; font-style: italic">						Basically, Pixels are stored within 3 sucessive Bytes</span>
<span style="color: #408080; font-style: italic">						in a BMP file, with one Byte each for Blue, Green and</span>
<span style="color: #408080; font-style: italic">						Red values (in that order).</span>
<span style="color: #408080; font-style: italic">						</span>
<span style="color: #408080; font-style: italic">						So, this reads the Bytes for each pixel, one at a time</span>
<span style="color: #408080; font-style: italic">						and then combines them into a single value which is</span>
<span style="color: #408080; font-style: italic">						the combined RGB pixel value.</span>
<span style="color: #408080; font-style: italic">						</span>
<span style="color: #408080; font-style: italic">						I left the code as I think it make it a little easier to</span>
<span style="color: #408080; font-style: italic">						understand what is going on, as well as how some of these</span>
<span style="color: #408080; font-style: italic">						calls can be optimized.</span>
<span style="color: #408080; font-style: italic">					*/</span>

					<span style="color: #408080; font-style: italic">/*</span>
<span style="color: #408080; font-style: italic">					var blue:int = fs.readUnsignedByte();</span>
<span style="color: #408080; font-style: italic">					var green:int = fs.readUnsignedByte();</span>
<span style="color: #408080; font-style: italic">					var red:int = fs.readUnsignedByte();</span>
<span style="color: #408080; font-style: italic">					</span>
<span style="color: #408080; font-style: italic">					pixels[position] = (red &lt;&lt; 16 ^ green &lt;&lt; 8 ^ blue);</span>
<span style="color: #408080; font-style: italic">					*/</span>

					<span style="color: #408080; font-style: italic">/*</span>
<span style="color: #408080; font-style: italic">						Here is the final code which is more efficient, as it only</span>
<span style="color: #408080; font-style: italic">						needs to make 2 read calls in order to get the values.</span>
<span style="color: #408080; font-style: italic">						</span>
<span style="color: #408080; font-style: italic">						Thanks to Thibault Imbert (bytearray.org) for pointing out</span>
<span style="color: #408080; font-style: italic">						and helping me understand the optimization.</span>
<span style="color: #408080; font-style: italic">					*/</span>

					<span style="color: #408080; font-style: italic">//bytes in file are in Blue, Green, Red order</span>
					<span style="color: #408080; font-style: italic">//int is 32 bits (8 bytes). So, we store the first two bytes of the pixel</span>
					<span style="color: #408080; font-style: italic">// (which contain the Red value), and</span>
					<span style="color: #408080; font-style: italic">//then shift everything over 1 byte (8bits) to make room for</span>
					<span style="color: #408080; font-style: italic">//the green and blue values (remember the file is little endian), which we</span>
					<span style="color: #408080; font-style: italic">// then write into the int in the right position</span>
					<span style="color: #408080; font-style: italic">//The final value has the colors in the correct order (Red, Green, Blue)</span>

					<span style="color: #008000; font-weight: bold">var</span> pixelValue<span style="color: #666666">:</span>uint <span style="color: #666666">=</span> fs.readUnsignedByte() <span style="color: #666666">|</span> fs.readUnsignedShort() <span style="color: #666666">&lt;&lt;</span> <span style="color: #666666">8;</span>
					pixels[position] <span style="color: #666666">=</span> pixelValue<span style="color: #666666">;</span>
				}

				<span style="color: #408080; font-style: italic">//we are at the end of the row, so now we have to move the cursor</span>
				<span style="color: #408080; font-style: italic">//forward so it ends on a multiple of 4</span>
				<span style="color: #008000; font-weight: bold">if</span>(padding)
				{
					fs.position <span style="color: #666666">+=</span> padding<span style="color: #666666">;</span>
				}
			}

			<span style="color: #408080; font-style: italic">//done reading file, close stream.</span>
			fs.close();

			<span style="color: #408080; font-style: italic">//create a Rectangle with width / height of Bitmap</span>
			<span style="color: #008000; font-weight: bold">var</span> rect<span style="color: #666666">:</span><span style="color: #008000">Rectangle</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">Rectangle</span>(<span style="color: #666666">0,</span> <span style="color: #666666">0,</span> bmpWidth<span style="color: #666666">,</span> bmpHeight);

			<span style="color: #408080; font-style: italic">//create the BitmapData object to hold hold the BMP data.</span>
			<span style="color: #408080; font-style: italic">//we do a red fill here so it is easier to see if we have any errors</span>
			<span style="color: #408080; font-style: italic">//in our code</span>
			<span style="color: #008000; font-weight: bold">var</span> bmpData<span style="color: #666666">:</span><span style="color: #008000">BitmapData</span> <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #008000">BitmapData</span>(bmpWidth<span style="color: #666666">,</span> bmpHeight<span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">false</span><span style="color: #666666">,</span> <span style="color: #666666">0</span>xFF0000);

			<span style="color: #408080; font-style: italic">//copy the BMP pixel data into the BitmapData</span>
			bmpData.setVector(rect<span style="color: #666666">,</span> pixels);

			<span style="color: #408080; font-style: italic">//create a new Bitmap instance using the BitmapData</span>
			<span style="color: #008000; font-weight: bold">var</span> bitmap<span style="color: #666666">:</span>Bitmap <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">new</span> Bitmap(bmpData);
			bitmap.x <span style="color: #666666">=</span> <span style="color: #666666">10;</span>
			bitmap.y <span style="color: #666666">=</span> <span style="color: #666666">10;</span>

			<span style="color: #408080; font-style: italic">//add Bitmap to the display list</span>
			addChild(bitmap);
		}
	}
}
</pre>
</div>
<p>&nbsp;</p>
<p>You can download the example from <a href="/blog/files/examples/BMPViewer.zip">here</a>.</p>
<p>Thanks to <a href="http://www.theflashblog.com">Lee</a> for his presentation, and <a href="http://www.bytearray.org">Thibault Imber</a>t who helped me understand some of the details around endianes, as well as made some suggestions for optimizations.</p>
<p>If you are interested in learning more, I strong suggest watching L<a href="http://www.fitc.ca/media/">ee&#8217;s FITC Presentation</a>.</p>
<img src="http://feeds.feedburner.com/~r/MikeChambers/~4/CW2dIG9piF0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mikechambers.com/blog/2009/09/17/parsing-and-displaying-bmp-files-via-actionscript/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://www.mikechambers.com/blog/2009/09/17/parsing-and-displaying-bmp-files-via-actionscript/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 0.621 seconds --><!-- Cached page served by WP-Cache -->
