<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Andy Li’s Blog - Flash</title><link href="https://blog.onthewings.net/" rel="alternate"></link><link href="http://feeds.feedburner.com/tag/flash/feed/atom.xml" rel="self"></link><id>https://blog.onthewings.net/</id><updated>2012-03-04T22:19:00+08:00</updated><entry><title>Head-tracking motion-parallax 3D in haXe/Flash</title><link href="https://blog.onthewings.net/2012/03/04/head-tracking-motion-parallax-3d-in-haxe-flash/" rel="alternate"></link><published>2012-03-04T22:19:00+08:00</published><updated>2012-03-04T22:19:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2012-03-04:/2012/03/04/head-tracking-motion-parallax-3d-in-haxe-flash/</id><summary type="html">&lt;iframe allowfullscreen="" class="video" frameborder="0" height="390" src="//www.youtube.com/embed/U6PePKJHOSw" width="640"&gt;&lt;/iframe&gt;
&lt;p&gt;Here above is my haXe implementation of head-tracking 3D, creating
motion-parallax effect using Away3D 4. You can play with the &lt;a href="http://andyli.github.com/MotionParallaxDemo/"&gt;live
demo&lt;/a&gt; or &lt;a href="https://github.com/andyli/MotionParallaxDemo"&gt;grab the source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This type of head tracking &lt;span class="caps"&gt;VR&lt;/span&gt; has been around for quite a long time. The
first popular one should be &lt;a href="http://www.youtube.com/watch?v=Jd3-eiid-Uw"&gt;Johnny Lee’s Wiimote …&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;iframe allowfullscreen="" class="video" frameborder="0" height="390" src="//www.youtube.com/embed/U6PePKJHOSw" width="640"&gt;&lt;/iframe&gt;
&lt;p&gt;Here above is my haXe implementation of head-tracking 3D, creating
motion-parallax effect using Away3D 4. You can play with the &lt;a href="http://andyli.github.com/MotionParallaxDemo/"&gt;live
demo&lt;/a&gt; or &lt;a href="https://github.com/andyli/MotionParallaxDemo"&gt;grab the source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This type of head tracking &lt;span class="caps"&gt;VR&lt;/span&gt; has been around for quite a long time. The
first popular one should be &lt;a href="http://www.youtube.com/watch?v=Jd3-eiid-Uw"&gt;Johnny Lee’s Wiimote hack&lt;/a&gt;, back in 2007,
 built in C# running as a desktop app. Two years later it appeared in
the browser, &lt;a href="http://ricardocabello.com/blog/post/643"&gt;a Flash version made by Mr. doob&lt;/a&gt;. But it was merely a
hack and far from accurate comparing to Johnny Lee’s. Boffswana also
created &lt;a href="http://www.boffswana.com/news/?p=498"&gt;one&lt;/a&gt; in the same year (2009), and then &lt;a href="http://www.boffswana.com/news/?p=950"&gt;an improved one&lt;/a&gt;
with better head tracking algorithm. Sadly Boffswana hasn’t release the source.&lt;/p&gt;
&lt;p&gt;Head tracking and camera movement is relatively simple, since there are
so many libs for these. The tricky part is the perspective
projection matrix. The projection point (the head), unlike most of the
implementation assumption, isn’t always perpendicular to the projection
surface (screen).&lt;/p&gt;
&lt;p&gt;Simplest implementation would ignore the problem. It places a camera at
the position of viewer’s head and render it to the screen, like what Mr.
doob did. The problem is illustrated below.&lt;/p&gt;
&lt;p&gt;When viewer’s head is perpendicular to the screen, everything is
perfectly aligned:&lt;/p&gt;
&lt;p&gt;&lt;img alt="when head is perpendicular to screen" src="/files/2012/animated.79104.gif"/&gt;&lt;/p&gt;
&lt;p&gt;However, when the viewer moves, for example to the left, there is
misalignment of the rendering on screen and the “actual” position of the
virtual object:&lt;/p&gt;
&lt;p&gt;&lt;img alt="when viewer moved to left" src="/files/2012/animated.61275.gif"/&gt;&lt;/p&gt;
&lt;p&gt;Knowing little about C#, it is hard for me to dig out Johnny Lee’s
matrix code. I found the suitable code form the paper “Generalized
Perspective Projection” from &lt;a href="http://csc.lsu.edu/~kooima/misc.html"&gt;Robert Kooima&lt;/a&gt;. It is written in C++,
but translating it to haXe isn’t hard, just remember matrix in OpenGL is
&lt;a href="http://en.wikipedia.org/wiki/Row-major_order#Column-major_order"&gt;column-major order&lt;/a&gt; but Flash’s is &lt;a href="http://en.wikipedia.org/wiki/Row-major_order#Row-major_order"&gt;row-major order&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Head-detection is done using &lt;a href="http://code.google.com/r/andy-hxmarilena/"&gt;my fork&lt;/a&gt; of &lt;a href="http://code.google.com/p/hxmarilena/"&gt;hxmarilena&lt;/a&gt;. My fork is
simply some &lt;span class="caps"&gt;API&lt;/span&gt; changes and switching the &lt;span class="caps"&gt;XML&lt;/span&gt; parsing from
&lt;a href="http://haxe.org/api/flash9/xml/xml"&gt;flash.xml.&lt;span class="caps"&gt;XML&lt;/span&gt;&lt;/a&gt; to &lt;a href="http://haxe.org/api/xml"&gt;Xml&lt;/a&gt; so it may be used in C++ target in the
future. In order to reduce jittering, I’ve included a simple optical
flow tracking on the head. It is a block-matching process applied to
four points on previous head detection result. The optical flow tracking
result is merged to head-detection result by a ratio. It improved a bit,
but I guess to address the problem it is better to port some better
algorithms, like &lt;a href="http://web.mac.com/jsaragih/FaceTracker/FaceTracker.html"&gt;FaceTracker&lt;/a&gt;, in the future.&lt;/p&gt;
&lt;p&gt;Finally, remember you can play with the &lt;a href="http://andyli.github.com/MotionParallaxDemo/"&gt;live demo&lt;/a&gt; and &lt;a href="https://github.com/andyli/MotionParallaxDemo"&gt;it is open
source&lt;/a&gt;.&lt;/p&gt;</content><category term="3D"></category><category term="experiment"></category><category term="Flash"></category><category term="Haxe"></category></entry><entry><title>How to know objects are really GC’ed in Flash(AS3)</title><link href="https://blog.onthewings.net/2010/10/18/how-to-know-objects-are-really-gced-in-flash-as3/" rel="alternate"></link><published>2010-10-18T01:48:00+08:00</published><updated>2010-10-18T01:48:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2010-10-18:/2010/10/18/how-to-know-objects-are-really-gced-in-flash-as3/</id><summary type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Memory_leak"&gt;Memory leak&lt;/a&gt; is a bug that pretty hard to deal with. Usually people
use some profilers to observer the memory usage while stressing the
program, if there is no increase of memory usage after repeating calls
of a function, we can conclude there is no memory leak in that function …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Memory_leak"&gt;Memory leak&lt;/a&gt; is a bug that pretty hard to deal with. Usually people
use some profilers to observer the memory usage while stressing the
program, if there is no increase of memory usage after repeating calls
of a function, we can conclude there is no memory leak in that function.
It is of course fine to detect memory leak in this way, but it is always
good to have a way that asserts your objects are really &lt;a href="http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)" title="garbage collection"&gt;&lt;span class="caps"&gt;GC&lt;/span&gt;&lt;/a&gt;‘ed at
some point.&lt;/p&gt;
&lt;p&gt;The trick is to use a &lt;code&gt;Dictionary&lt;/code&gt; with weak-reference keys and check its
element count. It is already quite popular in the Java world but look
like there aren’t many Flash devs talking about it.&lt;/p&gt;
&lt;p&gt;A simple demo on how to write such test, &lt;a href="http://wonderfl.net/c/ohTv"&gt;source is available in
wonderfl&lt;/a&gt;:&lt;/p&gt;
&lt;script src="http://wonderfl.net/blogparts/ohTv/js" type="text/javascript"&gt;&lt;/script&gt;</content><category term="Flash"></category><category term="trick"></category></entry><entry><title>CanvasBlock: a GM script to block canvas tag (should we…or can we?)</title><link href="https://blog.onthewings.net/2010/04/13/canvasblock-a-gm-script-to-block-canvas-tag-should-we-or-can-we/" rel="alternate"></link><published>2010-04-13T02:41:00+08:00</published><updated>2010-04-13T02:41:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2010-04-13:/2010/04/13/canvasblock-a-gm-script-to-block-canvas-tag-should-we-or-can-we/</id><summary type="html">&lt;p&gt;&lt;span class="caps"&gt;HTML5&lt;/span&gt; is believed to be the Flash killer and will replace Flash in the
future. Eventually those Flash-haters will become canvas-haters, so a
canvas-blocking GreaseMonkey script will be useful (at least they think
it will be).&lt;/p&gt;
&lt;p&gt;I myself was making it for fun. I don’t think we should block …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;span class="caps"&gt;HTML5&lt;/span&gt; is believed to be the Flash killer and will replace Flash in the
future. Eventually those Flash-haters will become canvas-haters, so a
canvas-blocking GreaseMonkey script will be useful (at least they think
it will be).&lt;/p&gt;
&lt;p&gt;I myself was making it for fun. I don’t think we should block any &lt;span class="caps"&gt;HTML5&lt;/span&gt;
tags anytime since it is a part of the web, just like I do not agree
people blocking Flash. What is interesting is, seems like we
cannot effectively block the canvas tag, which will be discussed later
in this post.&lt;/p&gt;
&lt;h3&gt;Features&lt;/h3&gt;
&lt;p&gt;I made the script blocks not only canvas tag but also video tag and
audio tag. It is because Flash is going to be replaced by all the three
tags but not only canvas. Video and audio can be as annoying as canvas.&lt;/p&gt;
&lt;p&gt;Like those Flash-blockers, the blocked contents are replaced by a line
of text, “Click to show xxxx”. You may click on it to get back the
blocked content.&lt;/p&gt;
&lt;p&gt;CanvasBlock is tested on Firefox 3.6 on Mac, Firefox 3.5 on Ubuntu and
Chrome on Ubuntu. Other platforms should works too.&lt;/p&gt;
&lt;h3&gt;Implementing the script&lt;/h3&gt;
&lt;p&gt;I used haXe instead of writing pure &lt;span class="caps"&gt;JS&lt;/span&gt;. No big reason here, just to see
if it is possible. Turn out there is no big difference from using &lt;span class="caps"&gt;JS&lt;/span&gt;,
you just need to copy all the meta data to the compiled &lt;span class="caps"&gt;JS&lt;/span&gt; file. And the
events listener need to be assigned by &lt;code&gt;addEventListener&lt;/code&gt; instead of
something like &lt;code&gt;onclick = function ...&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Detecting &lt;span class="caps"&gt;HTML5&lt;/span&gt; tags is easier than detecting Flash objects. Firstly,
the tags are standardized meaning you can simply use
&lt;code&gt;getElementsByTagName&lt;/code&gt;. For Flash objects you need to check the params
of the &lt;code&gt;object&lt;/code&gt; and the &lt;code&gt;embed&lt;/code&gt; tags, which is a bit troublesome.
Secondly, currently no one (at least not much ppl) is creating canvas
tags on the fly, unlike for Flash the standard way is to use swfobject.
So I can detect the tags once the &lt;span class="caps"&gt;DOM&lt;/span&gt; is ready, no need to wait for the
execution of the page’s &lt;span class="caps"&gt;JS&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Replacing the tags and saving them for later retrieval is easy too.
Using normal &lt;span class="caps"&gt;JS&lt;/span&gt; method will work.&lt;/p&gt;
&lt;h3&gt;The tags are blocked but…&lt;/h3&gt;
&lt;p&gt;The script is functional and I went to do some more testing. Blocking
video and audio seems ok, but there is some problem of blocking canvas.&lt;/p&gt;
&lt;h4&gt;Possibility of Freezing/Crashing&lt;/h4&gt;
&lt;p&gt;I went to &lt;a href="http://www.chromeexperiments.com/"&gt;ChromeExperiments&lt;/a&gt; and randomly picked &lt;a href="http://www.chromeexperiments.com/detail/asteroids-game/"&gt;one&lt;/a&gt;. You know
what? The browser froze.&lt;/p&gt;
&lt;p&gt;So, look like after I blocked the canvas, the &lt;span class="caps"&gt;JS&lt;/span&gt; on the page which is
used to draw thing on the canvas originally, is still there trying to
work on the canvas. And this become a big problem since I don’t
know exactly which &lt;span class="caps"&gt;JS&lt;/span&gt; function is going to work on
canvas, because different web page have different functions, so no way I
can work on that. You can completely disable &lt;span class="caps"&gt;JS&lt;/span&gt;, but this is not a
CanvasBlock should do.&lt;/p&gt;
&lt;p&gt;Browser froze and an timeout message was shown after blocking canvas:
&lt;img alt="Browser freezed and an timeout message was shown after blocking canvas" src="/files/2010/errorAfterBlockingCanvas.png"/&gt;&lt;/p&gt;
&lt;p&gt;However, I have tested some more web page and they are ok with the
blocking script. So maybe only some complex &lt;span class="caps"&gt;JS&lt;/span&gt; will have this problem.
But anyway the possibility of freezing a browser is not a good thing.&lt;/p&gt;
&lt;h4&gt;No significant reduction on &lt;span class="caps"&gt;CPU&lt;/span&gt; usage&lt;/h4&gt;
&lt;p&gt;The remaining &lt;span class="caps"&gt;JS&lt;/span&gt; script  problem reminded me to test on the &lt;span class="caps"&gt;CPU&lt;/span&gt; usage.
And the result is, blocking canvas does not bring significant reduction
on &lt;span class="caps"&gt;CPU&lt;/span&gt; usage. See the following screenshots, which is using &lt;a href="http://www.chromeexperiments.com/detail/aquarium/"&gt;another
Chrome experiment&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Page opened, canvas blocked. However &lt;span class="caps"&gt;CPU&lt;/span&gt; usage still rise to a
very high level:
&lt;img alt="Page opened, canvas blocked. However CPU usage still rise to a
very high level." src="/files/2010/cpuUsage-1.png"/&gt;&lt;/p&gt;
&lt;p&gt;Clicked to show back the canvas. &lt;span class="caps"&gt;CPU&lt;/span&gt; usage rose even higher,
but not much difference:
&lt;img alt="Clicked to show back the canvas. CPU usage rose even higher,
but not much difference." src="/files/2010/cpuUsage-2.png"/&gt;&lt;/p&gt;
&lt;p&gt;So what’s that mean? Again if I want to block the real &lt;span class="caps"&gt;CPU&lt;/span&gt; hog, I should
block the &lt;span class="caps"&gt;JS&lt;/span&gt; with the canvas. But again, stated above, it is not
possible to block the right function without blocking all &lt;span class="caps"&gt;JS&lt;/span&gt;.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Blocking canvas can only introduce little benefit on &lt;span class="caps"&gt;CPU&lt;/span&gt; usage but give
you possibility of freezing/crashing!&lt;/p&gt;
&lt;p&gt;Let’s look at Flash again. Flash can be blocked easily because
ActionScript is included in the swf. Removing the swf from the
page automatically removes the associated scripts. Also, usually &lt;span class="caps"&gt;JS&lt;/span&gt; does
not control a Flash object so it is pretty safe to kick Flash out
without dealing with the remained &lt;span class="caps"&gt;JS&lt;/span&gt;. From this point of view, seems
that Flash is more user friendly than canvas, and &lt;span class="caps"&gt;HTML5&lt;/span&gt; ads will be more
annoying than Flash ads…&lt;/p&gt;
&lt;p&gt;If you want to try, you may install the script from &lt;a href="http://userscripts.org/scripts/show/74216"&gt;CanvasBlock’s page
on userscripts.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You’re also welcome to get the haXe source from &lt;a href="http://github.com/andyli/CanvasBlock"&gt;CanvasBlock’s Github
repo&lt;/a&gt;.&lt;/p&gt;</content><category term="Flash"></category><category term="Haxe"></category><category term="HTML5"></category><category term="JavaScript"></category></entry><entry><title>Colorblink - An AIR app that simulates how color blind people see Flash and images</title><link href="https://blog.onthewings.net/2010/02/19/colorblink-an-air-app-that-simulates-how-color-blind-people-see-flash-and-images/" rel="alternate"></link><published>2010-02-19T20:55:00+08:00</published><updated>2010-02-19T20:55:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2010-02-19:/2010/02/19/colorblink-an-air-app-that-simulates-how-color-blind-people-see-flash-and-images/</id><summary type="html">&lt;p&gt;&lt;img alt="Select color blind type from the menu." src="/files/2010/colorblink-demo.png"/&gt;&lt;/p&gt;
&lt;p&gt;Accessibility is a an important part of both web and game design. And
for web and game design, one of the popular tool is Flash. That means
very often you need to ensure accessibility in Flash. However there are
still not many tools available even for simple things like color …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Select color blind type from the menu." src="/files/2010/colorblink-demo.png"/&gt;&lt;/p&gt;
&lt;p&gt;Accessibility is a an important part of both web and game design. And
for web and game design, one of the popular tool is Flash. That means
very often you need to ensure accessibility in Flash. However there are
still not many tools available even for simple things like color blind
simulation… so I write my own:)&lt;/p&gt;
&lt;p&gt;&amp;gt;&amp;gt; &lt;a href="http://github.com/andyli/Colorblink/raw/master/Colorblink.air"&gt;download installer (.air)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It’s a very simple &lt;span class="caps"&gt;AIR&lt;/span&gt; app. You open it, drop a swf file on its window,
select the color blind type and that’s it.&lt;/p&gt;
&lt;p&gt;The inner of Colorblink is using a Pixel Bender filter, applying to the
whole application. The algorithm is just a color transform matrix, found
in &lt;a href="http://homepage.mac.com/lpetrich/ColorBlindnessSim/ColorBlindnessSim.html"&gt;a Java Color-Blindness Simulators&lt;/a&gt;. That simulator have more
simulation config, which I used only the simplest one.&lt;/p&gt;
&lt;p&gt;This is also my first time using a git repo. So &lt;a href="http://github.com/andyli/Colorblink"&gt;go to have a look&lt;/a&gt;,
see if you can fork it for more features.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;One thing is, there is
problem loading Flex applications into Colorblink… I don’t know how to
read the loaded app’s default width and height and then resize it… So,
if you want to test your Flex app, &lt;a href="http://github.com/andyli/Colorblink/tree/master/src/net/onthewings/filters/"&gt;get the filter&lt;/a&gt; and apply it to
your app manually (can’t be easier).&lt;/del&gt;&lt;br/&gt;
Now you can load Flex swf or even html file! But the app wouldn’t
resize automatically since the size cannot be determined. If Colorblink
does not work for you, you can still always &lt;a href="http://github.com/andyli/Colorblink/tree/master/src/net/onthewings/filters/"&gt;get the filter&lt;/a&gt; and apply
it to your app manually (can’t be easier).&lt;/p&gt;
&lt;p&gt;Oh, yes, there is a simulation of what a dog sees… So, design some
game for your dogs in your free time…&lt;/p&gt;</content><category term="Flash"></category><category term="Flex"></category><category term="Pixel Bender"></category><category term="web usability design and engineering"></category></entry><entry><title>Chroma key and thresholding in Flash (Pixel Bender), revised</title><link href="https://blog.onthewings.net/2009/12/10/chroma-key-and-thresholding-in-flash-pixel-bender-revised/" rel="alternate"></link><published>2009-12-10T18:12:00+08:00</published><updated>2009-12-10T18:12:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2009-12-10:/2009/12/10/chroma-key-and-thresholding-in-flash-pixel-bender-revised/</id><summary type="html">&lt;p&gt;&lt;img alt="yellowFiltered" src="/files/2009/yellowFiltered.png" title="yellowFiltered"/&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a href="/files/2009/chromaKey.html"&gt;Demo&lt;/a&gt; (Click to toggle filter)&lt;/h3&gt;
&lt;p&gt;&lt;a href="/files/2009/chromaKey.zip"&gt;source (Flex project including pbk)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I have been very busy since the last few weeks… so the chroma key
filter was put aside for a long time until today :)&lt;/p&gt;
&lt;p&gt;I have used conditional compile in the filter to avoid having if-else in
the runtime, hopefully …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="yellowFiltered" src="/files/2009/yellowFiltered.png" title="yellowFiltered"/&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a href="/files/2009/chromaKey.html"&gt;Demo&lt;/a&gt; (Click to toggle filter)&lt;/h3&gt;
&lt;p&gt;&lt;a href="/files/2009/chromaKey.zip"&gt;source (Flex project including pbk)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I have been very busy since the last few weeks… so the chroma key
filter was put aside for a long time until today :)&lt;/p&gt;
&lt;p&gt;I have used conditional compile in the filter to avoid having if-else in
the runtime, hopefully can increase performance… Anyone volunteer to
measure it and post the different?&lt;/p&gt;</content><category term="experiment"></category><category term="Flash"></category><category term="Pixel Bender"></category></entry><entry><title>AS3/JS string concatenation methods performance test</title><link href="https://blog.onthewings.net/2009/10/09/as3-js-string-concatenation-methods-performace-test/" rel="alternate"></link><published>2009-10-09T23:25:00+08:00</published><updated>2009-10-09T23:25:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2009-10-09:/2009/10/09/as3-js-string-concatenation-methods-performace-test/</id><summary type="html">&lt;p&gt;When writing &lt;a href="https://blog.onthewings.net/2009/10/08/brainflash-the-as3-brainfuck-interpreter/"&gt;BrainFlash&lt;/a&gt;, I was thinking if the string concatenations
for program output will slow down the whole interpreter. That is because
I was once hit that a year ago when dealing with &lt;span class="caps"&gt;XML&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;I asked for better handling methods over &lt;a href="http://stackoverflow.com/questions/1536260/string-concatenation-is-extremly-slow-when-input-is-large"&gt;StackOverflow&lt;/a&gt;. It is
interesting that some of the answers …&lt;/p&gt;</summary><content type="html">&lt;p&gt;When writing &lt;a href="https://blog.onthewings.net/2009/10/08/brainflash-the-as3-brainfuck-interpreter/"&gt;BrainFlash&lt;/a&gt;, I was thinking if the string concatenations
for program output will slow down the whole interpreter. That is because
I was once hit that a year ago when dealing with &lt;span class="caps"&gt;XML&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;I asked for better handling methods over &lt;a href="http://stackoverflow.com/questions/1536260/string-concatenation-is-extremly-slow-when-input-is-large"&gt;StackOverflow&lt;/a&gt;. It is
interesting that some of the answers shown that using “+=” is already
the fastest. But I still want to know more about that, so I wrote my own
simple testing program, which is below:&lt;/p&gt;
&lt;h3&gt;ActionScript version&lt;/h3&gt;
&lt;p&gt;&lt;object data="/files/2009/test.swf" height="400" id="swf0a0b1" style="visibility: visible;" type="application/x-shockwave-flash" width="600"&gt;&lt;param name="wmode" value="opaque"/&gt;&lt;param name="menu" value="true"/&gt;&lt;param name="quality" value="high"/&gt;&lt;param name="bgcolor" value="#FFFFFF"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="/files/2009/test.zip"&gt;source code&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Methods used are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;str += concateString;&lt;/li&gt;
&lt;li&gt;str = str.concat(concateString);&lt;/li&gt;
&lt;li&gt;array.push(concateString); … str = array.join(“”);&lt;/li&gt;
&lt;li&gt;vector.push(concateString); … str = vector.join(“”);&lt;/li&gt;
&lt;li&gt;byteArray.writeUTFBytes(concateString); … str = byteArray.readUTFBytes(byteArray.length);&lt;/li&gt;
&lt;li&gt;byteArray.writeMultiByte(concateString,”us-ascii”); … str = byteArray.readMultiByte(str.length,”us-ascii”);&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The result shows that fastest method is using &lt;code&gt;+=&lt;/code&gt;, but using
Array/Vector is still very close to it. Using ByteArray is slow and with
&lt;span class="caps"&gt;ASCII&lt;/span&gt; instead of &lt;span class="caps"&gt;UTF&lt;/span&gt;-8 is even slower…&lt;/p&gt;
&lt;p&gt;And all the methods are performed reasonably fast, what is slow is when
showing the resulting string on TextArea… It takes a few seconds! But
when it is drawn, run it again and it will become normal speed, maybe
there is some caching?&lt;/p&gt;
&lt;h3&gt;JavaScript version&lt;/h3&gt;
&lt;p&gt;I coded a JavaScript port too. &lt;a href="/files/2009/string-concatenation-methods-performace-test.html"&gt;See it here.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Methods used are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;str += concateString;&lt;/li&gt;
&lt;li&gt;str = str.concat(concateString);&lt;/li&gt;
&lt;li&gt;array.push(concateString); … str = array.join(“”);&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Interesting enough, the result is very similar to &lt;span class="caps"&gt;AS3&lt;/span&gt;. It is the
opposite of what we believe using the Array trick will let it performs
faster. &lt;code&gt;+=&lt;/code&gt; is the fastest in most cases, if not, that’s not much difference.&lt;/p&gt;
&lt;p&gt;I’ve only tested in &lt;span class="caps"&gt;IE8&lt;/span&gt;(Win), Firefox 3 (Win/Mac), Safari 4 (Win/Mac),
Chrome 3 (Win). The really really really interesting part is in Chrome
3, using the concat method of String is x7000 &lt;span class="caps"&gt;SLOWER&lt;/span&gt; than the other
two!! What are your results?&lt;/p&gt;</content><category term="experiment"></category><category term="Flash"></category><category term="JavaScript"></category></entry><entry><title>BrainFlash, the AS3 BrainFuck interpreter</title><link href="https://blog.onthewings.net/2009/10/08/brainflash-the-as3-brainfuck-interpreter/" rel="alternate"></link><published>2009-10-08T03:11:00+08:00</published><updated>2009-10-08T03:11:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2009-10-08:/2009/10/08/brainflash-the-as3-brainfuck-interpreter/</id><summary type="html">&lt;p&gt;If you haven’t heard about &lt;a href="http://www.muppetlabs.com/~breadbox/bf/"&gt;Brainfuck&lt;/a&gt; yet, it is a famous esoteric
programming language. If you want to know why it has such a name take a
look at its hello-world program source code (from &lt;a href="http://en.wikipedia.org/wiki/Brainfuck#Hello_World.21"&gt;Wikipedia&lt;/a&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="c"&gt;           initialize counter (cell #0) to 10&lt;/span&gt;
&lt;span class="k"&gt;[&lt;/span&gt;&lt;span class="c"&gt;                       use loop to set the next four …&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;If you haven’t heard about &lt;a href="http://www.muppetlabs.com/~breadbox/bf/"&gt;Brainfuck&lt;/a&gt; yet, it is a famous esoteric
programming language. If you want to know why it has such a name take a
look at its hello-world program source code (from &lt;a href="http://en.wikipedia.org/wiki/Brainfuck#Hello_World.21"&gt;Wikipedia&lt;/a&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="c"&gt;           initialize counter (cell #0) to 10&lt;/span&gt;
&lt;span class="k"&gt;[&lt;/span&gt;&lt;span class="c"&gt;                       use loop to set the next four cells to 70/100/30/10&lt;/span&gt;
&lt;span class="c"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="c"&gt;             add  7 to cell #1&lt;/span&gt;
&lt;span class="c"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="c"&gt;         add 10 to cell #2&lt;/span&gt;
&lt;span class="c"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt;                   add  3 to cell #3&lt;/span&gt;
&lt;span class="c"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="c"&gt;                     add  1 to cell #4&lt;/span&gt;
&lt;span class="c"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt;&lt;span class="c"&gt;                 decrement counter (cell #0)&lt;/span&gt;
&lt;span class="k"&gt;]&lt;/span&gt;&lt;span class="c"&gt;&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;                   print 'H'&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;                     print 'e'&lt;/span&gt;
&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;              print 'l'&lt;/span&gt;
&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;                       print 'l'&lt;/span&gt;
&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;                   print 'o'&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;                   print ' '&lt;/span&gt;
&lt;span class="nv"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;++&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt; print 'W'&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;                      print 'o'&lt;/span&gt;
&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;                   print 'r'&lt;/span&gt;
&lt;span class="nb"&gt;---&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;---&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;               print 'l'&lt;/span&gt;
&lt;span class="nb"&gt;---&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;---&lt;/span&gt;&lt;span class="c"&gt; &lt;/span&gt;&lt;span class="nb"&gt;--&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;             print 'd'&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;                     print '!'&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;                      print '\n'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;the above program can be written as:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;++++++++++&lt;/span&gt;&lt;span class="k"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;+++++++&lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;++++++++++&lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt;&lt;span class="k"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;++&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;+++++++&lt;/span&gt;&lt;span class="nt"&gt;..&lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;++&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;+++++++++++++++&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;+++&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;------&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;--------&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;.&lt;/span&gt;&lt;span class="c"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So now you should know how lovely the language is and why I need to
write a interpreter in Flash: now you can manipulate a ByteArray with
BrainFuck code!!! And ya, the name of my interpreter is even more
friendly than the language’s name! :)&lt;/p&gt;
&lt;p&gt;&lt;a href="/files/2009/brainflashDemo.html"&gt;Here is the result demo&lt;/a&gt; (&lt;a href="/files/2009/brainflashDemo.zip"&gt;source code here&lt;/a&gt;), type in a program
and its input then click run. The default program is to add up two
single-digit integers. And the output is correct only if the sum is
single-digit too. And again the code is from Wikipedia. You may find
other BrainFuck source code to test from &lt;a href="http://esoteric.sange.fi/brainfuck/bf-source/prog/"&gt;Panu Kalliokoski’s Brainfuck
Archive&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The interpreter is written by only looking at its command description.
There are some bugs as I know. For example when inputting multiple
lines, the output may have wrong formatting. And it can not have dynamic
input like having inputs in a infinite loop. Actually any infinite loop
will freeze your browser.&lt;/p&gt;
&lt;p&gt;I don’t think I will go to improve it anytime soon. So please, don’t use
it in production (will anyone??).&lt;/p&gt;</content><category term="experiment"></category><category term="Flash"></category></entry><entry><title>Pixel Bender port of Scale2x and Scale3x</title><link href="https://blog.onthewings.net/2009/09/28/pixel-bender-port-of-scale2x-and-scale3x/" rel="alternate"></link><published>2009-09-28T03:35:00+08:00</published><updated>2009-09-28T03:35:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2009-09-28:/2009/09/28/pixel-bender-port-of-scale2x-and-scale3x/</id><summary type="html">&lt;p&gt;&lt;img alt="scale2x" src="/files/2009/scale2x.png" title="scale2x"/&gt;&lt;/p&gt;
&lt;p&gt;When I first saw the &lt;a href="http://en.nicoptere.net/?p=6"&gt;Scale2x, scale3x &lt;span class="caps"&gt;AS3&lt;/span&gt;&lt;/a&gt; I am impressed. The
algorithm is from &lt;a href="http://scale2x.sourceforge.net/algorithm.html"&gt;scale2x sourceforge project&lt;/a&gt; and the &lt;span class="caps"&gt;AS3&lt;/span&gt; port is
coded as a class that is very easy to reuse. Surely the &lt;span class="caps"&gt;AS3&lt;/span&gt; port author
nicoptere can make a &lt;span class="caps"&gt;PB&lt;/span&gt; port too as you may find out …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="scale2x" src="/files/2009/scale2x.png" title="scale2x"/&gt;&lt;/p&gt;
&lt;p&gt;When I first saw the &lt;a href="http://en.nicoptere.net/?p=6"&gt;Scale2x, scale3x &lt;span class="caps"&gt;AS3&lt;/span&gt;&lt;/a&gt; I am impressed. The
algorithm is from &lt;a href="http://scale2x.sourceforge.net/algorithm.html"&gt;scale2x sourceforge project&lt;/a&gt; and the &lt;span class="caps"&gt;AS3&lt;/span&gt; port is
coded as a class that is very easy to reuse. Surely the &lt;span class="caps"&gt;AS3&lt;/span&gt; port author
nicoptere can make a &lt;span class="caps"&gt;PB&lt;/span&gt; port too as you may find out many &lt;span class="caps"&gt;PB&lt;/span&gt; cool stuff
over &lt;a href="http://en.nicoptere.net/"&gt;his blog&lt;/a&gt;, but my pixel bending desire force me to do it myself :P&lt;/p&gt;
&lt;p&gt;Here below the video shows my demo. I get a camera capture stream and
used &lt;a href="http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&amp;amp;extid=1760025"&gt;Posterizer which is downloaded from Pixel Bender Exchange&lt;/a&gt; to
convert the image to 4-color-only, and than use the scale2x filter to
enlarge the low resolution capture. The top-left corner thumbnail-like
image is actually the original 1:1 input(160*120).&lt;/p&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="390" src="//www.youtube.com/embed/3PHPc2it4ww" width="640"&gt;&lt;/iframe&gt;
&lt;p&gt;It is quite interesting to see for scale2x, &lt;span class="caps"&gt;PB&lt;/span&gt;’s version nearly doubles
the performance of &lt;span class="caps"&gt;AS3&lt;/span&gt;’s. But for scale3x, there is not much different
between &lt;span class="caps"&gt;PB&lt;/span&gt; and &lt;span class="caps"&gt;AS3&lt;/span&gt;. I think it is because scale3x has too many if-else
which &lt;span class="caps"&gt;PB&lt;/span&gt; is not strong at.&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;BTW&lt;/span&gt;, I discovered a bug in &lt;span class="caps"&gt;PB&lt;/span&gt; while coding this. The bug make my code
much longer as I work-a-round it… I reported it to the &lt;a href="http://forums.adobe.com/thread/497374"&gt;&lt;span class="caps"&gt;PB&lt;/span&gt; forum&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="/files/2009/pbScaleX.html"&gt;Demo app&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="/files/2009/pbScaleX.zip"&gt;Demo app’s Flex project with Pixel Bender source&lt;/a&gt; (The shorter but
buggy versions are included too.)&lt;/p&gt;</content><category term="Flash"></category><category term="Pixel Bender"></category></entry><entry><title>Bicubic resampling by Pixel Bender</title><link href="https://blog.onthewings.net/2009/08/25/bicubic-resampling-by-pixel-bender/" rel="alternate"></link><published>2009-08-25T07:51:00+08:00</published><updated>2009-08-25T07:51:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2009-08-25:/2009/08/25/bicubic-resampling-by-pixel-bender/</id><summary type="html">&lt;p&gt;There is &lt;a href="http://www.brooksandrus.com/blog/2009/03/11/bilinear-resampling-with-flash-player-and-pixel-bender/"&gt;bilinear resampling by Pixel Bender&lt;/a&gt; already, why not
bicubic too?&lt;/p&gt;
&lt;p&gt;With the very helpful &lt;a href="http://www.paulinternet.nl/?page=bicubic"&gt;Java implementation&lt;/a&gt;, I can get bicubic
resampling running in Pixel Bender in hours.&lt;/p&gt;
&lt;p&gt;Here is my result, along with the resampling results in PhotoShop as a comparison:&lt;/p&gt;
&lt;p&gt;Source image (4x4), scaled by your browser …&lt;/p&gt;</summary><content type="html">&lt;p&gt;There is &lt;a href="http://www.brooksandrus.com/blog/2009/03/11/bilinear-resampling-with-flash-player-and-pixel-bender/"&gt;bilinear resampling by Pixel Bender&lt;/a&gt; already, why not
bicubic too?&lt;/p&gt;
&lt;p&gt;With the very helpful &lt;a href="http://www.paulinternet.nl/?page=bicubic"&gt;Java implementation&lt;/a&gt;, I can get bicubic
resampling running in Pixel Bender in hours.&lt;/p&gt;
&lt;p&gt;Here is my result, along with the resampling results in PhotoShop as a comparison:&lt;/p&gt;
&lt;p&gt;Source image (4x4), scaled by your browser):&lt;/p&gt;
&lt;p&gt;&lt;img alt="Source image (4x4), scaled by your browser)" class="size-full wp-image-506 " height="200" scale="0" src="/files/2009/16color.png" title="16color image" width="200"/&gt;&lt;/p&gt;
&lt;p&gt;Source image enlarged in &lt;span class="caps"&gt;PS&lt;/span&gt; (nearest neighbor):&lt;/p&gt;
&lt;p&gt;&lt;img alt="Source image enlarged in PS (nearest neighbor)" class="size-full wp-image-507 " height="200" scale="0" src="/files/2009/16color_psNearest.png" title="16color_psNearest" width="200"/&gt;&lt;/p&gt;
&lt;p&gt;Bicubic resampling by Pixel Bender:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Bicubic resampling by Pixel Bender" class="size-full wp-image-508 " height="200" scale="0" src="/files/2009/16color_pbBicubic.png" title="16color_pbBicubic" width="200"/&gt;&lt;/p&gt;
&lt;p&gt;There is some difference with PhotoShop’s versions (below), hope it’s
not my mistake…&lt;/p&gt;
&lt;p&gt;Bicubic resampling by PhotoShop:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Bicubic resampling by PhotoShop." class="size-full wp-image-509 " height="200" scale="0" src="/files/2009/16color_psBicubic.png" title="16color_psBicubic" width="200"/&gt;&lt;/p&gt;
&lt;p&gt;Bicubic smoother by PhotoShop:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Bicubic smoother in PhotoShop" class="size-full wp-image-510 " height="200" scale="0" src="/files/2009/16color_psBicubicSmoother.png" title="16color_psBicubicSmoother" width="200"/&gt;&lt;/p&gt;
&lt;p&gt;Bicubic sharper by PhotoShop:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Bicubic sharper in PhotoShop" class="size-full wp-image-511 " height="200" scale="0" src="/files/2009/16color_psBicubicShaper.png" title="16color_psBicubicShaper" width="200"/&gt;&lt;/p&gt;
&lt;p&gt;My codes can be downloaded below:&lt;br/&gt;
&lt;a href="/files/2009/bicubicResampling.zip"&gt;Bicubic resampling sample program source (with &lt;span class="caps"&gt;PB&lt;/span&gt; source)&lt;/a&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Update:&lt;br/&gt;
Notified by author of the Java version, the Java code was wrong and has
been updated. Here below is my updated code:&lt;br/&gt;
&lt;a href="/files/2010/bicubicResampling.zip"&gt;Bicubic resampling sample program source (with &lt;span class="caps"&gt;PB&lt;/span&gt; source)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;updated output of &lt;span class="caps"&gt;PB&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="updated output of PB" src="/files/2009/pbBicubic.png"/&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Update (2010-11-17):&lt;br/&gt;
Once again notified by Paul, the author of the Java version, there is
something need to be updated. Here below is my updated code:&lt;br/&gt;
&lt;a href="/files/2009/bicubicResampling1.zip"&gt;Bicubic resampling sample program source (with &lt;span class="caps"&gt;PB&lt;/span&gt; source)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;updated output of &lt;span class="caps"&gt;PB&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="updated output of PB" src="/files/2009/pbBicubic1.png"/&gt;&lt;/p&gt;</content><category term="Flash"></category><category term="Flex"></category><category term="Pixel Bender"></category></entry><entry><title>Playing with chroma key and thresholding in Flash (with Pixel Bender)</title><link href="https://blog.onthewings.net/2009/08/18/playing-with-chroma-key-and-thresholding-in-flash-with-pixel-bender/" rel="alternate"></link><published>2009-08-18T06:22:00+08:00</published><updated>2009-08-18T06:22:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2009-08-18:/2009/08/18/playing-with-chroma-key-and-thresholding-in-flash-with-pixel-bender/</id><summary type="html">&lt;p&gt;While &lt;a href="http://www.flickr.com/photos/andy-li/sets/72157621818199411/"&gt;traveling with my gf in Europe&lt;/a&gt;, I’m planning to develop a
better technique to use color marker in FLARtoolkit (which I’ve &lt;a href="https://blog.onthewings.net/2009/05/23/flartoolkit-trick-use-a-colored-marker/"&gt;tried
before&lt;/a&gt;).&lt;/p&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="390" src="//www.youtube.com/embed/coDZ7VUogh4" width="640"&gt;&lt;/iframe&gt;
&lt;p&gt;For the first step of doing so is to find a algorithm of matching
colors. Using blend mode “difference” on the image is not …&lt;/p&gt;</summary><content type="html">&lt;p&gt;While &lt;a href="http://www.flickr.com/photos/andy-li/sets/72157621818199411/"&gt;traveling with my gf in Europe&lt;/a&gt;, I’m planning to develop a
better technique to use color marker in FLARtoolkit (which I’ve &lt;a href="https://blog.onthewings.net/2009/05/23/flartoolkit-trick-use-a-colored-marker/"&gt;tried
before&lt;/a&gt;).&lt;/p&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="390" src="//www.youtube.com/embed/coDZ7VUogh4" width="640"&gt;&lt;/iframe&gt;
&lt;p&gt;For the first step of doing so is to find a algorithm of matching
colors. Using blend mode “difference” on the image is not flexible and
may not fit all situations. I decided to calculate the difference by
comparing hue, saturation and brightness of the colors and then
threshold the image.&lt;/p&gt;
&lt;p&gt;This is very similar to (if not exactly) doing &lt;a href="http://en.wikipedia.org/wiki/Chroma_key"&gt;chroma key&lt;/a&gt;. Maybe
there is some awesome beautiful chroma key algorithm but I can’t find a
fast and flexible enough to do so. If you know one, please tell me. :)&lt;/p&gt;
&lt;p&gt;One problem I faced is choosing between color space models. &lt;span class="caps"&gt;RGB&lt;/span&gt; surely
wouldn’t be the choice since it do not give hue value directly. There
are &lt;span class="caps"&gt;HSV&lt;/span&gt; and &lt;span class="caps"&gt;HSL&lt;/span&gt; I found to be quite suitable. The two models share the
same algorithm to calculate hue but have different ones for saturation
and brightness. After reading the &lt;a href="http://en.wikipedia.org/wiki/HSL_and_HSV"&gt;algorithms&lt;/a&gt;, my decision is… try
both. :P&lt;/p&gt;
&lt;p&gt;Another problem is how to preform thresholding. First method is after
calculating the pixel difference, add the difference in hue, saturation
and brightness altogether with weightings and do a one-time threshold to
the grayscale image. Second method is calculate the difference and give
threshold limits to the three channels (H,S,V or H,S,L), only the pixels
pass all the three thresholds will be white. First method should be more
easily to incorporate with other filters developed for &lt;span class="caps"&gt;AR&lt;/span&gt; (like the very
hot &lt;a href="http://blog.inspirit.ru/?p=322"&gt;adaptive thresholding&lt;/a&gt;), but the second method can be more
precise.  Finally I tried both too…&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: large;"&gt;&lt;strong&gt;&lt;a href="/files/2009/colorDifference.html"&gt;Here is the result&lt;/a&gt;&lt;/strong&gt;&lt;/span&gt;. While
I have set some default values to the filters, be sure to play around
with the values when you change the target color. There wouldn’t be a
set of values that fits all methods and situations. :)&lt;/p&gt;
&lt;p&gt;I’ll try integrate it with FLARtoolkit and release the source when it is
ready, be sure to check back soon. :)&lt;/p&gt;
&lt;p&gt;Update:&lt;br/&gt;
&lt;a href="https://blog.onthewings.net/2009/12/10/chroma-key-and-thresholding-in-flash-pixel-bender-revised/"&gt;Source and new demo is here!&lt;/a&gt;&lt;/p&gt;</content><category term="experiment"></category><category term="Flash"></category><category term="Flex"></category><category term="Pixel Bender"></category></entry></feed>