<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Jozef Chúťka&#039;s blog &#187; BitmapData</title>
	<atom:link href="http://blog.yoz.sk/tag/bitmapdata/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.yoz.sk</link>
	<description>My life, my work</description>
	<lastBuildDate>Tue, 31 Jan 2012 12:40:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>A Sound In Image Experiment</title>
		<link>http://blog.yoz.sk/2011/10/a-sound-in-image-experiment/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-sound-in-image-experiment</link>
		<comments>http://blog.yoz.sk/2011/10/a-sound-in-image-experiment/#comments</comments>
		<pubDate>Tue, 25 Oct 2011 09:58:45 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[BitmapData]]></category>
		<category><![CDATA[extract]]></category>
		<category><![CDATA[SampleDataEvent]]></category>
		<category><![CDATA[Sound]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=3075</guid>
		<description><![CDATA[There are some usefull apis since Flash Player 10, I have never been playing with. Yesterday, I realized one experiment with Sound + SampleDataEvent and created quick demo for converting music into a bitmap and vice versa. There is a Sound.extract() method in ActionScript allowing you to grab raw sound data from a sound object. [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.yoz.sk/wp-content/uploads/violin.jpg" alt="" title="violin" width="200" height="100" class="alignleft size-full wp-image-3076" /></p>
<p>There are some usefull apis since Flash Player 10, I have never been playing with. Yesterday, I realized one experiment with <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html">Sound</a> + <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/SampleDataEvent.html">SampleDataEvent</a> and created quick demo for converting music into a bitmap and vice versa.</p>
<p>There is a <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html#extract()">Sound.extract()</a> method in ActionScript allowing you to grab raw sound data from a sound object. It provides you ByteArray of 32-bit floating-point values, which can be converted to a Number using ByteArray.readFloat(). The resulting values are -1 < value < 1...</p>
<p><span id="more-3075"></span></p>
<p>I tried to add and multiply the Number to get unsigned integer and it appeared that only first 16 bytes are changing while the rest 16 remains unused (0xffff). I did not get any further to investigate if it is related to the type conversion or its a limitation of Sound api. While for BitmapData you provide 32 values (unsigned integers) and the converted sound value use only 16, next 16 bites can store additional sound value. That perfectly fits for left + right channel. BitmapData handles 32-bit ARGB values. In my case, left channel will occupy first AR, right channel GB values, so please do not expect the result to be Mona Lisa portrait, but rather it is a chaotic (noise like) color and alpha result. Following image contains 5 seconds of Vivaldi:</p>
<p><img src="http://blog.yoz.sk/examples/soundInImage/soundInImage.png" alt=""/></p>
<p>If you are able match image width with music rythm, some more interesting result may appear. And here is the demo player:</p>
<p><script type="text/javascript" src="http://wonderfl.net/blogparts/2rEF/js"></script>
<p class="ttlBpWonderfl" style="width: 465px; margin: 0; text-align: right; font-size: 11px;"><a href="http://wonderfl.net/c/2rEF" title="Sound In Image">Sound In Image &#8211; wonderfl build flash online</a></p>
<p>There is a lot of commented code in the demo, feel free to uncomment for generating images from your mp3s.</p>
<p>Some quick math about image size vs. music length:</p>
<ul>
<li>in sound, the audio data is always exposed as 44100 Hz stereo</li>
<li>so there is 88200 32-bit floating-point values per second (left + right channel)</li>
<li>two values can be stored in a pixel, that results in 44100 pixels per second</li>
<li>that means you can store almost <strong>18 seconds in 1024&#215;768 ARGB image</strong></li>
</ul>
<p>It would be nice to see how can image compression, watermark etc. affect the resulting sound/size. Or how would some image filters affect the resulting sound&#8230; A lot of experiments ahead <img src='http://blog.yoz.sk/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2011/10/a-sound-in-image-experiment/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Quick Tip: OSMF VideoPlayer Screenshot</title>
		<link>http://blog.yoz.sk/2011/09/quick-tip-osmf-videoplayer-screenshot/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=quick-tip-osmf-videoplayer-screenshot</link>
		<comments>http://blog.yoz.sk/2011/09/quick-tip-osmf-videoplayer-screenshot/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 08:23:02 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[BitmapData]]></category>
		<category><![CDATA[Matrix]]></category>
		<category><![CDATA[OSMF]]></category>
		<category><![CDATA[screenshot]]></category>
		<category><![CDATA[VideoPlayer]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=3053</guid>
		<description><![CDATA[Your video is usualy resized and played in a custom sized rectangle, but if you need to capture the fullscreen screenshot you may be tempted to gather the original size screenshot by resizing the whole component or its part. Its not the best practice, while you need to resize and move back and forth the [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.yoz.sk/wp-content/uploads/screenshot1.png" alt="" title="screenshot1" width="200" height="100" class="alignleft size-full wp-image-3054" /></p>
<p>Your video is usualy resized and played in a custom sized rectangle, but if you need to capture the fullscreen screenshot you may be tempted to gather the original size screenshot by resizing the whole component or its part. Its not the best practice, while you need to resize and move back and forth the component etc. Here is a quick tip to make a fullsize screenshot from spark osmf based <a href="http://opensource.adobe.com/wiki/display/flexsdk/Spark+VideoPlayer">VideoPlayer</a> using <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html?filter_flash=cs5&#038;filter_flashplayer=10.2&#038;filter_air=2.6">Matrix</a>.</p>
<p><span id="more-3053"></span></p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;s:Application xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
               xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
               xmlns:mx=&quot;library://ns.adobe.com/flex/mx&quot;&gt;
    &lt;fx:Script&gt;
        &lt;![CDATA[
            import spark.components.VideoDisplay;
            private function capture():void
            {
                var videoDisplay:VideoDisplay = video.videoDisplay;
                var videoObject:Video = videoDisplay.videoObject;
                var bitmapData:BitmapData = new BitmapData(videoObject.videoWidth, videoObject.videoHeight, true, 0x000000);
                var matrix:Matrix = videoObject.transform.matrix.clone();
                matrix.scale(videoObject.videoWidth / videoObject.width, videoObject.videoHeight / videoObject.height);
                matrix.tx = 0;
                matrix.ty = 0;
                bitmapData.draw(videoObject, matrix);
                image.source = new Bitmap(bitmapData);
            }
        ]]&gt;
    &lt;/fx:Script&gt;

    &lt;s:layout&gt;
        &lt;s:VerticalLayout /&gt;
    &lt;/s:layout&gt;

    &lt;s:VideoPlayer id=&quot;video&quot; source=&quot;video.flv&quot; autoPlay=&quot;false&quot; width=&quot;300&quot; height=&quot;200&quot;/&gt;
    &lt;s:Button label=&quot;capture&quot; click=&quot;capture()&quot;/&gt;
    &lt;mx:Image id=&quot;image&quot;/&gt;
&lt;/s:Application&gt;</pre>
<p>Remember, you need a correct crossdomain policy to access video bitmapData.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2011/09/quick-tip-osmf-videoplayer-screenshot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Processing BitmapData.getPixels() With PHP</title>
		<link>http://blog.yoz.sk/2010/10/processing-bitmapdata-getpixels-with-php/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=processing-bitmapdata-getpixels-with-php</link>
		<comments>http://blog.yoz.sk/2010/10/processing-bitmapdata-getpixels-with-php/#comments</comments>
		<pubDate>Mon, 25 Oct 2010 11:35:41 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[BitmapData]]></category>
		<category><![CDATA[ByteArray]]></category>
		<category><![CDATA[compress]]></category>
		<category><![CDATA[imagecolorallocate]]></category>
		<category><![CDATA[imagesetpixel]]></category>
		<category><![CDATA[unpack]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=2547</guid>
		<description><![CDATA[Have you ever worked with BitmapData.getPixels() method? This method generates a byte array from a rectangular region of pixel data. Writes an unsigned integer (a 32-bit unmultiplied pixel value) for each pixel into the byte array. Thats sounds good, but what is it good for to have a ByteArray full of integers? There is not [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever worked with <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#getPixels()">BitmapData.getPixels()</a> method? This method <em>generates a byte array from a rectangular region of pixel data. Writes an unsigned integer (a 32-bit unmultiplied pixel value) for each pixel into the byte array</em>. Thats sounds good, but what is it good for to have a ByteArray full of integers? There is not even a decoder for this format on my backend?!&#8230; Well, this format is so cool, and easy to access that you do are able to write your own decoder e.g. in PHP.</p>
<p>The resulting bytes are 32-bit unsigned integers for each pixel represented by AARRGGBB format, followed by another pixels and so on e.g.:</p>
<pre class="brush: plain; title: ; notranslate">AA RR GG BB:
-- -- -- --
FF FF 00 00
00 00 FF 00</pre>
<p><span id="more-2547"></span></p>
<p>First pixel is full opaque red color, second pixel is full transparent green color. That sounds good enough to use with <a href="http://php.net/manual/en/function.imagesetpixel.php">imagesetpixel()</a>, that requires color in <a href="http://www.php.net/manual/en/function.imagecolorallocate.php">almost identic format</a>, however PHP GD library recognizes alpha values from 0 to 127 in reversed logic (127 full transparent, 0 full opaque). So we only need to change the alpha value and we are good to go:</p>
<pre class="brush: plain; title: ; notranslate">AA -&gt; AA (php)
--    --
FF -&gt; 00
00 -&gt; 7F</pre>
<p>What are we going to do is:</p>
<ul>
<li>this format does not know about width and height of image, we have to define it manualy</li>
<li>access pixels (unsigned integers) from byte array (<a href="http://cz.php.net/manual/en/function.unpack.php">unpack()</a> is the fastest method for this in PHP i guess)</li>
<li>iterate over each pixel / color</li>
<li>get color value and transform to PHP alpha logic
<ul>
<li><strong>$color>>24</strong> returns alpha value (0-255), what we need is to divide it by two (0-127 for php) so <strong>$color&gt;&gt;25</strong> works fine</li>
<li>inversed logic requires values to be changed from 0-127 to 127-0: <strong>0x7f-AA</strong></li>
<li>shift alpha value back to its correct position <strong>AA&lt;&lt;24</strong></li>
<li>add original RRGGBB values to our new alpha <strong>AA|($color&amp;0xffffff)</strong></li>
</ul>
</li>
<li>pass transformed color value into imagesetpixel() with correct x, y coordinate</li>
</ul>
<p>This process should return correct image identifier. Lets have a new PHP function imagecreatefrombmdstring()</p>
<pre class="brush: php; title: ; notranslate">&lt;?php
function imagecreatefrombmdstring($bytes, $width, $height)
{
	$img=imagecreatetruecolor($width, $height);
	imagealphablending($img, false);
	imagesavealpha($img, true);

	$x=0;
	$y=0;
	$colors=unpack(&quot;N*&quot;, $bytes);
	foreach($colors as $color)
	{
		imagesetpixel($img, $x, $y, (0x7f-($color&gt;&gt;25)&lt;&lt;24)|($color&amp;0xffffff));
		if(++$x==$width)
		{
			$x=0;
			$y++;
		}
	}
	return $img;
}</pre>
<p>The ActionScript code may look something like this, this method is in fact very fast on client side:</p>
<pre class="brush: as3; title: ; notranslate">var bitmapData:BitmapData = ...
var bytes:Bytes=bitmapData.getPixels(bitmapData.rect);
var loader:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest();
request.url = &quot;our.php&quot;;
request.contentType = &quot;application/octet-stream&quot;;
request.method = URLRequestMethod.POST;
request.data = bytes;
loader.load(request);</pre>
<p>To optimize it even more, use <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/ByteArray.html#compress()">ByteArray.compress()</a> to compress bytes before sending, now you should get binary request not much bigger than length of the same request containing <a href="http://blog.yoz.sk/2010/06/quick-tip-fastest-actionscript-pngencoder/">PNG encoded</a> image bytes. On PHP side use <a href="http://php.net/manual/en/function.gzuncompress.php">gzuncompress()</a> to get raw bytes.</p>
<p>Why did I developer/used this method of sending image to server? Well, I was not able to find fast enought/asynchronous PNG encoder. By using this technique, I was able to scale the getPixels+compress process into multiple frames (asynchronously) in order to create smooth upload process (using <a href="http://code.google.com/p/in-spirit/wiki/MultipartURLLoader">MultipartURLLoader</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2010/10/processing-bitmapdata-getpixels-with-php/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Pixel Bender Disco</title>
		<link>http://blog.yoz.sk/2010/02/pixel-bender-disco/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pixel-bender-disco</link>
		<comments>http://blog.yoz.sk/2010/02/pixel-bender-disco/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 11:24:09 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[BitmapData]]></category>
		<category><![CDATA[fps]]></category>
		<category><![CDATA[pixel bender]]></category>
		<category><![CDATA[Shader]]></category>
		<category><![CDATA[ShaderJob]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=1117</guid>
		<description><![CDATA[While playing with pixel bender, I created some simple sahders that when combined, reminds me of winamp visualizations effects. Feel free to use any in your own projects. Click and drag mouse to make some disco effects. (wait while page header flash finishes loading so it runs smoothly) Rotation pixel bender Blur pixel bender Colorize [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.yoz.sk/wp-content/uploads/pixelBenderDisco.jpg" alt="" title="pixelBenderDisco" width="200" height="100" class="alignleft size-full wp-image-1124" /></p>
<p>While playing with pixel bender, I created some simple sahders that when combined, reminds me of winamp visualizations effects. Feel free to use any in your own projects.</p>
<p><span id="more-1117"></span></p>
<p style="clear:both;">Click and drag mouse to make some disco effects. (wait while page header flash finishes loading so it runs smoothly)</p>
<p><iframe width="100%" height="300" style="border:none;" src="http://blog.yoz.sk/examples/pixelBenderDisco/"></iframe></p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; layout=&quot;absolute&quot;
    enterFrame=&quot;enterFrame()&quot; applicationComplete=&quot;init()&quot;
    backgroundColor=&quot;#ffffff&quot; frameRate=&quot;50&quot;
    mouseMove=&quot;mouseMoveHandler(event)&quot;
    mouseDown=&quot;mouseDownHandler(event)&quot;
    mouseUp=&quot;mouseUpHandler(event)&quot;&gt;
&lt;mx:Script&gt;
&lt;![CDATA[
    private var drawing:Boolean = false;
    private var color:uint = 0x0;
    private var bitmap:Bitmap = new Bitmap();
    private var lineX:Number = 0;

    [Bindable]
    private var fps:Number = 0;
    private var fpsDate:Date = new Date();
    private var fpsFrames:uint = 0;

    [Bindable]
    private var rotationTime:uint = 0;

    [Bindable]
    private var blurTime:uint = 0;

    [Bindable]
    private var colorizeTime:uint = 0;

    [Bindable]
    private var twirlTime:uint = 0;

    [Embed(source=&quot;../pbj/rotation.pbj&quot;, mimeType=&quot;application/octet-stream&quot;)]
    private static const ROTATION_CLASS:Class;
    private static const ROTATION_SHADER:Shader = new Shader(new ROTATION_CLASS());

    [Embed(source=&quot;../pbj/blur.pbj&quot;, mimeType=&quot;application/octet-stream&quot;)]
    private static const BLUR_CLASS:Class;
    private static const BLUR_SHADER:Shader = new Shader(new BLUR_CLASS());

    [Embed(source=&quot;../pbj/colorize.pbj&quot;, mimeType=&quot;application/octet-stream&quot;)]
    private static const COLORIZE_CLASS:Class;
    private static const COLORIZE_SHADER:Shader = new Shader(new COLORIZE_CLASS());

    [Embed(source=&quot;../pbj/twirl.pbj&quot;, mimeType=&quot;application/octet-stream&quot;)]
    private static const TWIRL_CLASS:Class;
    private static const TWIRL_SHADER:Shader = new Shader(new TWIRL_CLASS());

    private function init():void
    {
        placeholder.addChild(bitmap);
    }

    private function mouseDownHandler(event:MouseEvent):void
    {
        drawing = true;
        color = Math.random() * 0xffffff;
    }

    private function initGraphics():void
    {
        container.graphics.clear();
        container.graphics.moveTo(mouseX, mouseY);
        container.graphics.lineStyle(10, color, 1);
    }

    private function mouseUpHandler(event:MouseEvent):void
    {
        drawing = false;
    }

    private function mouseMoveHandler(event:MouseEvent):void
    {
        if(!drawing)
            return;
        container.graphics.lineTo(event.localX, event.localY);
    }

    private function countFps():void
    {
        if(++fpsFrames &lt; 10)
            return;
        fps = Math.round(1 / (new Date().time - fpsDate.time) * 10000);
        fpsDate = new Date();
        fpsFrames = 0;
    }

    private function get w():Number
    {
        return container.width;
    }

    private function get h():Number
    {
        return container.height;
    }

    private function enterFrame():void
    {
        countFps();

        if(!container || !container.width)
            return;

        var bitmapData:BitmapData = new BitmapData(w, h, true, 0x000000);
        bitmapData.draw(bitmap);
        if(rotationCheckBox.selected)
            addRotation(bitmapData, 0.1);
        if(blurCheckBox.selected)
            addBlur(bitmapData);
        if(colorizeCheckBox.selected)
            addColorize(bitmapData, color);
        if(twirlCheckBox.selected)
        {
            var radius:Number = Math.min(w / 2, h / 2);
            addTwirl(bitmapData, 10, new Point(w / 4, h / 2), radius);
            addTwirl(bitmapData, -10, new Point(w / 4 * 3, h / 2), radius);
        }

        addAutoFill();
        bitmapData.draw(container);

        bitmap.bitmapData = bitmapData;
        initGraphics();
    }

    private function addAutoFill():void
    {
        lineX = (lineX &gt; w) ? 0 : (lineX + 15);
        container.graphics.moveTo(lineX - 15, h / 3 * 2);
        container.graphics.lineTo(lineX, h / 3 * 2);
    }

    private function addRotation(bitmapData:BitmapData, rotation:Number):void
    {
        rotationTime = new Date().time;
        ROTATION_SHADER.data.src.input = bitmapData;
        ROTATION_SHADER.data.src.width = w;
        ROTATION_SHADER.data.src.height = h;
        ROTATION_SHADER.data.rotation.value = [rotation];
        ROTATION_SHADER.data.tx.value = [w / 2];
        ROTATION_SHADER.data.ty.value = [h / 2];

        var job:ShaderJob = new ShaderJob(ROTATION_SHADER, bitmapData);
        job.start(true);
        rotationTime = new Date().time - rotationTime;
    }

    private function addBlur(bitmapData:BitmapData):void
    {
        blurTime = new Date().time;
        BLUR_SHADER.data.src.input = bitmapData;
        BLUR_SHADER.data.src.width = w;
        BLUR_SHADER.data.src.height = h;

        var job:ShaderJob = new ShaderJob(BLUR_SHADER, bitmapData);
        job.start(true);
        blurTime = new Date().time - blurTime;
    }

    private function addColorize(bitmapData:BitmapData, color:uint):void
    {
        colorizeTime = new Date().time;
        var r:Number = ((color &gt;&gt; 16) &amp; 0xFF) / 0xFF - 0.5;
        var g:Number = ((color &gt;&gt; <img src='http://blog.yoz.sk/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> &amp; 0xFF) / 0xFF - 0.5;
        var b:Number = (color &amp; 0xFF) / 0xFF - 0.5;

        COLORIZE_SHADER.data.src.input = bitmapData;
        COLORIZE_SHADER.data.src.width = w;
        COLORIZE_SHADER.data.src.height = h;
        COLORIZE_SHADER.data.color.value = [r / 40, g / 40, b / 40];

        var job:ShaderJob = new ShaderJob(COLORIZE_SHADER, bitmapData);
        job.start(true);
        colorizeTime = new Date().time - colorizeTime;
    }

    private function addTwirl(bitmapData:BitmapData, angle:Number,
        center:Point, radius:Number):void
    {
        twirlTime = new Date().time;
        TWIRL_SHADER.data.oImage.input = bitmapData;
        TWIRL_SHADER.data.oImage.width = w;
        TWIRL_SHADER.data.oImage.height = h;
        TWIRL_SHADER.data.radius.value = [radius];
        TWIRL_SHADER.data.center.value = [center.x, center.y];
        TWIRL_SHADER.data.twirlAngle.value = [angle];

        var job:ShaderJob = new ShaderJob(TWIRL_SHADER, bitmapData);
        job.start(true);
        twirlTime = new Date().time - twirlTime;
    }
]]&gt;
&lt;/mx:Script&gt;
&lt;mx:UIComponent width=&quot;100%&quot; height=&quot;100%&quot; id=&quot;placeholder&quot; /&gt;
&lt;mx:Container id=&quot;container&quot; width=&quot;100%&quot; height=&quot;100%&quot; backgroundAlpha=&quot;0&quot;/&gt;
&lt;mx:VBox paddingLeft=&quot;10&quot; paddingTop=&quot;10&quot;&gt;
    &lt;mx:Text text=&quot;fps: {fps} / 50&quot; /&gt;
    &lt;mx:HBox&gt;
        &lt;mx:CheckBox id=&quot;rotationCheckBox&quot; selected=&quot;true&quot;/&gt;
        &lt;mx:Label text=&quot;rotation {rotationTime} ms&quot; /&gt;
    &lt;/mx:HBox&gt;
    &lt;mx:HBox&gt;
        &lt;mx:CheckBox id=&quot;blurCheckBox&quot; selected=&quot;true&quot;/&gt;
        &lt;mx:Label text=&quot;blur {blurTime} ms&quot; /&gt;
    &lt;/mx:HBox&gt;
    &lt;mx:HBox&gt;
        &lt;mx:CheckBox id=&quot;colorizeCheckBox&quot; selected=&quot;true&quot;/&gt;
        &lt;mx:Label text=&quot;colorize {colorizeTime} ms&quot; /&gt;
    &lt;/mx:HBox&gt;
    &lt;mx:HBox&gt;
        &lt;mx:CheckBox id=&quot;twirlCheckBox&quot; selected=&quot;false&quot;/&gt;
        &lt;mx:Label text=&quot;twirl {twirlTime} ms&quot; /&gt;
    &lt;/mx:HBox&gt;
&lt;/mx:VBox&gt;
&lt;/mx:Application&gt;</pre>
<p>Rotation pixel bender</p>
<pre class="brush: xml; title: ; notranslate">&lt;languageVersion : 1.0;&gt;

kernel RotationFilter
&lt;
	namespace : &quot;sk.yoz&quot;;
	vendor : &quot;Yoz&quot;;
	version : 1;
	description : &quot;Image rotation over transform point&quot;;
&gt;
{
	input image4 src;
	output pixel4 dst;

	parameter float tx
	&lt;
		minValue: float(0.0);
		maxValue: float(4096.0);
		defaultValue: float(0.0);
		description: &quot;The amount of movement along the x axis to the right, in pixels.&quot;;
	&gt;;

	parameter float ty
	&lt;
		minValue: float(0.0);
		maxValue: float(4096.0);
		defaultValue: float(0.0);
		description: &quot;The amount of movement down along the y axis, in pixels.&quot;;
	&gt;;

	parameter float rotation
	&lt;
		minValue: float(0.0);
		maxValue: float(4096.0);
		defaultValue: float(0.0);
		description: &quot;Rotation in radians&quot;;
	&gt;;

	void evaluatePixel()
	{
		float2 pos = outCoord();
		float rc = cos(rotation);
		float rs = sin(rotation);
		float dx = pos.x - tx;
		float dy = pos.y - ty;
		dst = sampleNearest(src, float2(
			tx + rc * dx + rs * dy,
			ty + rc * dy - rs * dx));
	}
}</pre>
<p>Blur pixel bender</p>
<pre class="brush: xml; title: ; notranslate">&lt;languageVersion : 1.0;&gt;

kernel BlurFilter
&lt;
	namespace : &quot;sk.yoz&quot;;
	vendor : &quot;Yoz&quot;;
	version : 1;
	description : &quot;Simple blur&quot;;
&gt;
{
	input image4 src;
	output pixel4 dst;

	void evaluatePixel()
	{
		float2 pos = outCoord();

		dst = 1.0 / 9.0 * (
			sampleNearest(src, pos - float2(-1.0, -1.0))
			+ sampleNearest(src, pos - float2(0.0, -1.0))
			+ sampleNearest(src, pos - float2(1.0, -1.0))
			+ sampleNearest(src, pos - float2(-1.0, 0.0))
			+ sampleNearest(src, pos - float2(0.0, 0.0))
			+ sampleNearest(src, pos - float2(1.0, 0.0))
			+ sampleNearest(src, pos - float2(-1.0, 1.0))
			+ sampleNearest(src, pos - float2(0.0, 1.0))
			+ sampleNearest(src, pos - float2(1.0, 1.0)));
	}
}</pre>
<p>Colorize pixel bender</p>
<pre class="brush: xml; title: ; notranslate">&lt;languageVersion : 1.0;&gt;

kernel ColorizeFilter
&lt;
	namespace : &quot;sk.yoz&quot;;
	vendor : &quot;Yoz&quot;;
	version : 1;
	description : &quot;Simple colorize&quot;;
&gt;
{
	input image4 src;
	output pixel4 dst;

	parameter float3 color
	&lt;
		minValue: float3(-1.0, -1.0, -1.0);
		maxValue: float3(1.0, 1.0, 1.0);
		defaultValue: float3(0.0, 0.0, 0.0);
		description: &quot;Color&quot;;
	&gt;;

	void evaluatePixel()
	{
		dst = sampleNearest(src, outCoord());
		dst.r += color.r;
		dst.g += color.g;
		dst.b += color.b;
	}
}</pre>
<p><a href="http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&#038;extid=1536021">Twirl pixel bender effect is available for download here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2010/02/pixel-bender-disco/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SmoothImage Class (update)</title>
		<link>http://blog.yoz.sk/2010/01/smoothimage-class/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=smoothimage-class</link>
		<comments>http://blog.yoz.sk/2010/01/smoothimage-class/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 15:54:28 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[Bitmap]]></category>
		<category><![CDATA[BitmapData]]></category>
		<category><![CDATA[ImageResizer]]></category>
		<category><![CDATA[ResizeEvent]]></category>
		<category><![CDATA[ResizeMath]]></category>
		<category><![CDATA[SmoothImage]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=955</guid>
		<description><![CDATA[While Flex uses bilinear resizing method when scaling images (event for Bitmap.smoothing() method), you won&#8217;t be able to get nice results when downscaling more than 2 times. Inspired by ImageResizer class I have also created SmoothImage Class. This object extends mx.Image and uses ImageResizer.bilinearIterative() class in order to generate smoother resized results. In following example [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.yoz.sk/wp-content/uploads/smoothImage1-200x101.jpg" alt="" title="smoothImage" width="200" height="101" class="alignleft size-medium wp-image-963" /></p>
<p>While Flex uses bilinear resizing method when scaling images (event for Bitmap.smoothing() method), you won&#8217;t be able to get nice results when downscaling more than 2 times. Inspired by <a href="http://blog.yoz.sk/2010/01/how-to-resize-an-image-with-actionscript/">ImageResizer class</a> I have also created SmoothImage Class. This object extends mx.Image and uses ImageResizer.bilinearIterative() class in order to generate smoother resized results.</p>
<p><span id="more-955"></span></p>
<p style="clear:both;">In following example mx.Image, <a href="http://cookbooks.adobe.com/post_A_better_smooth_Image_control-9409.html">SmoothImage</a> and <a href="http://classes.yoz.sk/sk/yoz/image/SmoothImage.as">sk.yoz.image.SmoothImage</a> used to demonstrate resizing original 1024x679px image.</p>
<p><iframe src="http://blog.yoz.sk/examples/smoothImage/" width="100%" height="300" style="border:none;"></iframe></p>
<p><a href="http://classes.yoz.sk/sk/yoz/image/SmoothImage.as">sk.yoz.image.SmoothImage</a> class:</p>
<pre class="brush: as3; title: ; notranslate">package sk.yoz.image
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.geom.Matrix;
    import flash.geom.Point;

    import mx.controls.Image;

    import sk.yoz.math.ResizeMath;

    public class SmoothImage extends Image
    {
        protected var _resizeFunction:String = &quot;bilinearIterative&quot;;
        protected var _iterationMultiplier:Number = 2;
        protected var resizedBitmap:Bitmap;

        public function SmoothImage()
        {
            super();
        }

        [Bindable(event=&quot;resizeFunctionChanged&quot;)]
        [Inspectable(category=&quot;Other&quot;, defaultValue=&quot;bilinearIterative&quot;,
            enumeration=&quot;bilinear,bilinearIterative&quot;)]
        public function set resizeFunction(value:String):void
        {
            if(value == resizeFunction)
                return;
            _resizeFunction = value;
            resizeBitmap();
        }

        public function get resizeFunction():String
        {
            return _resizeFunction;
        }

        [Bindable(event=&quot;iterationMultiplierChanged&quot;)]
        public function set iterationMultiplier(value:Number):void
        {
            if(value == iterationMultiplier)
                return;

            _iterationMultiplier = value;
            resizeBitmap();
        }

        public function get iterationMultiplier():Number
        {
            return _iterationMultiplier;
        }

        override protected function updateDisplayList(unscaledWidth:Number,
            unscaledHeight:Number):void
        {
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            resizeBitmap();
        }

        protected function resizeBitmap(... rest):void
        {
            if(!width || !height || !content)
                return;

            if(resizedBitmap &amp;&amp; resizedBitmap.parent)
                resizedBitmap.parent.removeChild(resizedBitmap);

            resizedBitmap = new Bitmap(resizedBitmapData);
            addChild(resizedBitmap);
            content.visible = false;
        }

        protected function get resizeMethod():String
        {
            return maintainAspectRatio ? ResizeMath.METHOD_LETTERBOX
                : ResizeMath.METHOD_RAW;
        }

        protected function get resizedBitmapData():BitmapData
        {
            var bitmapData:BitmapData;

            if(content is Bitmap)
            {
                bitmapData = Bitmap(content).bitmapData
            }
            else
            {
                bitmapData = new BitmapData(content.width / content.scaleX,
                    content.height / content.scaleY, true, 0);
                bitmapData.draw(content);
            }

            var dimensions:Point = ResizeMath.newDimensions(
                new Point(bitmapData.width, bitmapData.height),
                new Point(width, height), resizeMethod, true);

            return ImageResizer[resizeFunction](bitmapData, dimensions.x,
                dimensions.y, resizeMethod, true, iterationMultiplier);
        }
    }
}</pre>
<p>Update (Jan 27, 2010): in sk.yoz.image.SmoothImage</p>
<p>Update (Jun 14, 2010): in sk.yoz.image.SmoothImage</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2010/01/smoothimage-class/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to resize an image with ActionScript (update)</title>
		<link>http://blog.yoz.sk/2010/01/how-to-resize-an-image-with-actionscript/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-resize-an-image-with-actionscript</link>
		<comments>http://blog.yoz.sk/2010/01/how-to-resize-an-image-with-actionscript/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 12:31:43 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[BitmapData]]></category>
		<category><![CDATA[ImageResizer]]></category>
		<category><![CDATA[Matrix]]></category>
		<category><![CDATA[pixel bender]]></category>
		<category><![CDATA[Point]]></category>
		<category><![CDATA[resize]]></category>
		<category><![CDATA[ResizeMath]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=792</guid>
		<description><![CDATA[If you need to resize an image on client side, I mean real bitmapData resize (not just showing scaled), feel free to use ImageResizer class. This class takes bitmapData of source image, new width and height and resize method (defined by ResizeMath class), and returns new bitmapData of resized image. Update: It seems that bitmapData.draw() [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.yoz.sk/wp-content/uploads/imageResizeLanczos.jpg"><img src="http://blog.yoz.sk/wp-content/uploads/imageResizeLanczos-200x153.jpg" alt="imageResizeLanczos" title="imageResizeLanczos" width="200" height="153" class="alignleft size-medium wp-image-856" /></a></p>
<p>If you need to resize an image on client side, I mean real bitmapData resize (not just showing scaled), feel free to use ImageResizer class. This class takes bitmapData of <strong>source</strong> image, new <strong>width</strong> and <strong>height</strong> and <strong>resize method</strong> (defined by ResizeMath class), and returns new bitmapData of resized image.</p>
<p>Update: It seems that bitmapData.draw() method uses bilinear algorithm when scaling via Matrix. Bilinear algorithm gives you fine results when downscaling no more than 2 times (400px -&gt; 200px). So, I added <strong>bilinearIterative() method</strong> into ImageResizer class that creates resized bitmapData by multiple steps achieving <strong>much smoother results</strong>!</p>
<p><span id="more-792"></span></p>
<p style="clear:both;">Source of <a href="http://classes.yoz.sk/sk/yoz/image/ImageResizer.as">sk.yoz.image.ImageResizer</a> class:</p>
<pre class="brush: as3; title: ; notranslate">package sk.yoz.image
{
    import flash.display.BitmapData;
    import flash.geom.Matrix;
    import flash.geom.Point;

    import sk.yoz.math.ResizeMath;

    public class ImageResizer extends Object
    {
        public function ImageResizer()
        {
        }

        public static function bilinear(source:BitmapData, width:uint,
            height:uint, method:String, allowEnlarging:Boolean=true):BitmapData
        {
            var scale:Point = ResizeMath.scale(
                new Point(source.width, source.height),
                new Point(width, height), method, allowEnlarging);
            var result:BitmapData = new BitmapData(width, height, true, 0x0);
            var matrix:Matrix = new Matrix();
            matrix.scale(scale.x, scale.y);
            matrix.tx = (width - source.width * scale.x) / 2;
            matrix.ty = (height - source.height * scale.y) / 2;
            result.draw(source, matrix, null, null, null, true);
            return result;
        }

        public static function bilinearIterative(source:BitmapData, width:uint,
            height:uint, method:String, allowEnlarging:Boolean = true,
            iterationMultiplier:Number = 2):BitmapData
        {
            var w:uint = source.width;
            var h:uint = source.height;
            var result:BitmapData;
            while(!result || w != width || h != height)
            {
                w = source.width &gt; width
                    ? Math.max(w / iterationMultiplier, width)
                    : Math.min(w * iterationMultiplier, width);
                h = source.height &gt; height
                    ? Math.max(h / iterationMultiplier, height)
                    : Math.min(h * iterationMultiplier, height);
                result = bilinear(result || source, w, h, method,
                    allowEnlarging);
            }
            return result;
        }
    }
}</pre>
<p>Usage is pretty simple. You also gonna need <a href="http://classes.yoz.sk/sk/yoz/math/ResizeMath.as">sk.yoz.math.ResizeMath</a> class.</p>
<pre class="brush: as3; title: ; notranslate">var result:BitmapData = ImageResizer.bilinearIterative(sourceBitmapData, 100, 100,
    ResizeMath.METHOD_PAN_AND_SCAN);</pre>
<h2>Alternatives &amp; Benchmarking</h2>
<p>There are also another possible methods to resize/resample images. Read more about <a href="http://www.brooksandrus.com/blog/2009/03/11/bilinear-resampling-with-flash-player-and-pixel-bender/">bilinear resampling</a> and <a href="http://blog.onthewings.net/2009/08/25/bicubic-resampling-by-pixel-bender/">bicubic resampling</a> methods using pixel bender. I benchamrked all methods and here are the results:</p>
<pre class="brush: plain; title: ; notranslate">source    | result  | ImageResizer | ImageResizer        | Bilinear PB | Bicubic PB
          |         | bilinear()   | bilinearIterative() |             |
4x4       | 200x200 |         0 ms |                3 ms |       16 ms |      31 ms
946x946   | 200x200 |         0 ms |                7 ms |       16 ms |      47 ms
1200x1200 | 200x200 |         0 ms |                9 ms |       32 ms |      47 ms</pre>
<p>Comparing ImageResizer.bilinear() method with bilinear and bicubic pixel bender resizing. Even though, all methods are pretty fast, the results are far from beeing as good as <a href="http://en.wikipedia.org/wiki/Lanczos_algorithm">Lanczos algorithm</a> results (e.g. used in <a href="http://www.irfanview.com/">IrfanView</a>):</p>
<p><a href="http://blog.yoz.sk/wp-content/uploads/resizingMethodBenchmark1.jpg"><img src="http://blog.yoz.sk/wp-content/uploads/resizingMethodBenchmark1-200x189.jpg" alt="resizingMethodBenchmark" title="resizingMethodBenchmark" width="200" height="189" class="alignnone size-medium wp-image-854" /></a></p>
<p>Comparing ImageResizer.bilinear(), ImageResizer.bilinearIterative() and <a href="http://en.wikipedia.org/wiki/Lanczos_algorithm">Lanczos algorithm</a>:</p>
<p><a href="http://blog.yoz.sk/wp-content/uploads/imageResizeLanczos.jpg"><img src="http://blog.yoz.sk/wp-content/uploads/imageResizeLanczos-200x153.jpg" alt="imageResizeLanczos" title="imageResizeLanczos" width="200" height="153" class="alignnone size-medium wp-image-856" /></a></p>
<p>If you are looking for <a href="http://blog.yoz.sk/2009/10/bitmap-bitmapdata-bytearray/">transformation between BitmapData, Bitmap, ByteArray, read this article</a>. </p>
<p><strong>Update November 10, 2010</strong>: <a href="http://blog.yoz.sk/2010/11/lanczos-resampling-with-actionscript/">Lanczos Resampling With ActionScript</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2010/01/how-to-resize-an-image-with-actionscript/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Frame rate optimization</title>
		<link>http://blog.yoz.sk/2009/11/frame-rate-optimization/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=frame-rate-optimization</link>
		<comments>http://blog.yoz.sk/2009/11/frame-rate-optimization/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 15:05:49 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[active]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[BitmapData]]></category>
		<category><![CDATA[frameRate]]></category>
		<category><![CDATA[FrameRateOptimizator]]></category>
		<category><![CDATA[inactive]]></category>
		<category><![CDATA[MouseEvent]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[Stage]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=604</guid>
		<description><![CDATA[There has been a lot of articles written about how to optimize your flash / flex application frameRate. In most cases, you only need to have full frameRate when some animation is playing, or tweening etc., in other words when some visual changes are going on. FrameRateOptimizator class does exactly what you need. In default, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.yoz.sk/wp-content/uploads/graph-going-up.jpg"><img src="http://blog.yoz.sk/wp-content/uploads/graph-going-up-200x199.jpg" alt="graph-going-up" title="graph-going-up" width="200" height="199" class="alignleft size-medium wp-image-610" /></a></p>
<p>There has been a lot of <a href="http://theflashblog.com/?p=1138">articles written about how to optimize your flash / flex application frameRate</a>. In most cases, you only need to have full frameRate when some animation is playing, or tweening etc., in other words when some visual changes are going on. FrameRateOptimizator class does exactly what you need. In default, it uses full frameRate when visual changes and when it stops, optimizator automatically switches to lower frameRate. Optimizator uses bitmapData to compare last state with actual state to catch any visual changes. By default snapshot is executed two times per second in low frameRate (inactive state), or one time per second in full frameRate state (active state), taking approximately not more than 10ms per execution (fast enough).</p>
<ul style="clear:both;">
<li><a href="http://classes.yoz.sk/sk/yoz/optimization/FrameRateOptimizator.as">sk.yoz.optimization.FrameRateOptimizator</a></li>
<li>Application</li>
</ul>
<p><span id="more-604"></span></p>
<p>FrameRateOptimizator.as</p>
<pre class="brush: as3; title: ; notranslate">package sk.yoz.optimization
{
    import flash.display.BitmapData;
    import flash.display.DisplayObject;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.geom.Matrix;
    import flash.utils.Timer;

    public class FrameRateOptimizator extends EventDispatcher
    {
        public var frameRateActive:uint = 24;
        public var frameRateInactive:uint = 2;

        protected var snapshot:BitmapData;

        protected var fpsp:uint;
        protected var _fps:uint;
        protected var fpsTimer:Timer;

        protected var root:DisplayObject;
        protected var _forceActive:Boolean = false;
        protected var _forceInactive:Boolean = false;
        protected var _mouseMoveActivation:Boolean = false;
        protected var _samplingScale:Number = 1;
        protected var samplingMatrix:Matrix = new Matrix();

        protected var samplingPeriod:uint = 1000;
        protected var activityTimer:Timer;

        public var debug:Boolean = false;

        public function FrameRateOptimizator(root:DisplayObject,
            frameRateActive:uint = 24, frameRateInactive:uint = 2,
            samplingPeriod:uint = 1000, mouseMoveActivation:Boolean = false,
            samplingScale:Number = 1):void
        {
            super();

            this.root = root;
            this.frameRateActive = frameRateActive;
            this.frameRateInactive = frameRateInactive;
            this.samplingPeriod = samplingPeriod;
            this.mouseMoveActivation = mouseMoveActivation;
            this.samplingScale = samplingScale;

            root.addEventListener(Event.ENTER_FRAME, rootEnterFrame);

            fpsTimer = new Timer(1000);
            fpsTimer.addEventListener(TimerEvent.TIMER, fpsTimerHandler);
            fpsTimer.start();

            var type:String = TimerEvent.TIMER_COMPLETE;
            activityTimer = new Timer(samplingPeriod, 1);
            activityTimer.addEventListener(type, activityTimerComplete);

            isActive = true;
        }

        [Bindable(event=&quot;fpsChanged&quot;)]
        public function get fps():uint
        {
            return _fps;
        }

        protected function set fps(value:uint):void
        {
            if(_fps == value)
                return;
            _fps = value;
            dispatchEvent(new Event(&quot;fpsChanged&quot;));
        }

        public function set forceActive(value:Boolean):void
        {
            _forceActive = value;
            if(forceActive)
                isActive = true;
        }

        public function get forceActive():Boolean
        {
            return _forceActive;
        }

        public function set forceInactive(value:Boolean):void
        {
            _forceInactive = value;
            if(forceInactive)
                isActive = false;
        }

        public function get forceInactive():Boolean
        {
            return _forceInactive;
        }

        public function set mouseMoveActivation(value:Boolean):void
        {
            if(value == _mouseMoveActivation)
                return;
            _mouseMoveActivation = value;
            if(value)
                root.addEventListener(MouseEvent.MOUSE_MOVE, rootMouseMove);
            else
                root.removeEventListener(MouseEvent.MOUSE_MOVE, rootMouseMove);
        }

        public function get mouseMoveActivation():Boolean
        {
            return _mouseMoveActivation;
        }

        public function set isActive(value:Boolean):void
        {
            if(value &amp;&amp; !forceActive &amp;&amp; !forceInactive)
            {
                activityTimer.reset();
                activityTimer.start();
            }
            frameRate = suggestFrameRate(value);
        }

        public function set samplingScale(value:Number):void
        {
            _samplingScale = value;
            samplingMatrix = new Matrix();
            samplingMatrix.scale(value, value);
        }

        public function get samplingScale():Number
        {
            return _samplingScale;
        }

        protected function suggestFrameRate(active:Boolean):uint
        {
            if(forceActive)
                return frameRateActive;
            if(forceInactive)
                return frameRateInactive;
            return active ? frameRateActive : frameRateInactive;
        }

        protected function set frameRate(value:uint):void
        {
            if(value == frameRate)
                return;
            root.stage.frameRate = value;
            if(debug)
                trace(&quot;FrameRateOptimizator -&gt; frameRate = &quot; + value);
        }

        protected function get frameRate():uint
        {
            return root.stage.frameRate;
        }

        public function get isActive():Boolean
        {
            return frameRate == frameRateActive;
        }

        protected function rootEnterFrame(event:Event):void
        {
            fpsp++;
            if(!isActive &amp;&amp; rootChanged)
                isActive = true;
        }

        protected function rootMouseMove(event:MouseEvent):void
        {
            isActive = true;
        }

        protected function get rootChanged():Boolean
        {
            var changed:Boolean = true;
            var bitmapData:BitmapData;
            try
            {
                var d0:Date = new Date();
                bitmapData = new BitmapData(
                    root.width * samplingScale, root.height * samplingScale);
                bitmapData.draw(root, samplingMatrix);
                if(snapshot)
                    changed = bitmapData.compare(snapshot) != 0;
                snapshot = bitmapData;
                trace(new Date().time - d0.time, &quot;ms&quot;)
            }
            catch(error:Error)
            {
                snapshot = null;
                if(debug)
                    trace(&quot;FrameRateOptimizator Error: &quot; + error.message);
            }
            return changed;
        }

        protected function fpsTimerHandler(event:TimerEvent):void
        {
            protected::fps = fpsp;
            fpsp = 0;
        }

        protected function activityTimerComplete(event:TimerEvent):void
        {
            isActive = rootChanged;
        }
    }
}</pre>
<p>Application</p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
    applicationComplete=&quot;init()&quot;&gt;
&lt;mx:Script&gt;
&lt;![CDATA[
    import sk.yoz.optimization.FrameRateOptimizator;

    [Bindable]
    private var frameRateOptimizator:FrameRateOptimizator;

    private function init():void
    {
        frameRateOptimizator = new FrameRateOptimizator(this, 30);

        // trace new frameRate on change
        frameRateOptimizator.debug = true;

        // makes active frameRate on mouse move
        frameRateOptimizator.mouseMoveActivation = true;

        // always use active frameRate
        // frameRateOptimizator.forceActive = true;

        // always use inactive frameRate
        // frameRateOptimizator.forceInactive = true;

        // use active frameRate immediately
        //frameRateOptimizator.isActive = true;
    }
]]&gt;
&lt;/mx:Script&gt;
&lt;mx:VSlider/&gt;
&lt;/mx:Application&gt;</pre>
<p>Export code in debug mode and watch how frameRate changes (in trace console) when playing with slider. Try (un)comment mouseMoveActivation and see the difference.</p>
<p>Optimizer will not work if application contains any source object and (in the case of a Sprite or MovieClip object) all of its child objects do not come from the same domain as the caller, or are not in a content that is accessible to the caller by having called the Security.allowDomain() method. <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/BitmapData.html#draw()">Read more about BitmapData.draw() SecurityError</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2009/11/frame-rate-optimization/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bitmap, BitmapData, ByteArray&#8230;</title>
		<link>http://blog.yoz.sk/2009/10/bitmap-bitmapdata-bytearray/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=bitmap-bitmapdata-bytearray</link>
		<comments>http://blog.yoz.sk/2009/10/bitmap-bitmapdata-bytearray/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 12:26:40 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[Bitmap]]></category>
		<category><![CDATA[BitmapData]]></category>
		<category><![CDATA[ByteArray]]></category>
		<category><![CDATA[converting]]></category>
		<category><![CDATA[DisplayObject]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[Loader]]></category>
		<category><![CDATA[LoaderInfo]]></category>
		<category><![CDATA[url]]></category>
		<category><![CDATA[URLRequest]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=135</guid>
		<description><![CDATA[Lets see how to convert between Bitmap, BitmapData and ByteArray in few examples: DisplayObject to BitmapData BitmapData to Bitmap BitmapData to ByteArray URL (image) to ByteArray (asynchronous) URL (image) to BitmapData (asynchronous) ByteArray to BitmapData (asynchronous) DisplayObject to BitmapData. FYI DisplayObject is any visible object in flash (Sprite, MovieClip, Bitmap, UIComponent, Video etc&#8230;): BitmapData to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.yoz.sk/wp-content/uploads/bitmap_converting.png"><img src="http://blog.yoz.sk/wp-content/uploads/bitmap_converting-200x119.png" alt="bitmap_converting" title="bitmap_converting" width="200" height="119" class="alignleft size-medium wp-image-452" /></a></p>
<p>Lets see how to convert between Bitmap, BitmapData and ByteArray in few examples:</p>
<ul style="float:left;">
<li>DisplayObject to BitmapData</li>
<li>BitmapData to Bitmap</li>
<li>BitmapData to ByteArray</li>
<li>URL (image) to ByteArray (asynchronous)</li>
<li>URL (image) to BitmapData  (asynchronous) </li>
<li>ByteArray to BitmapData  (asynchronous) </li>
</ul>
<div style="clear:both;"></div>
<p><span id="more-135"></span></p>
<p>DisplayObject to BitmapData. FYI <a href="http://livedocs.adobe.com/flex/3/langref/flash/display/DisplayObject.html">DisplayObject is any visible object in flash</a> (Sprite, MovieClip, Bitmap, UIComponent, Video etc&#8230;):</p>
<pre class="brush: as3; title: ; notranslate">import flash.display.BitmapData;
var bitmapData:BitmapData = new BitmapData(button.width, button.height, false, 0xFFFFFF);
bitmapData.draw(button);
// result: bitmapData</pre>
<p>BitmapData to Bitmap:</p>
<pre class="brush: as3; title: ; notranslate">import flash.display.Bitmap;
var bitmap:Bitmap = new Bitmap(bitmapData);
// result: bitmap</pre>
<p>BitmapData to ByteArray. Requires jpeg / png or any other encoder. <a href="http://blog.yoz.sk/2009/10/actionscript-3-encoding-jpeg/">Read more about JPEG encoding here</a>:</p>
<pre class="brush: as3; title: ; notranslate">import mx.graphics.codec.JPEGEncoder;
import flash.utils.ByteArray;
var encoder:JPEGEncoder = new JPEGEncoder(90);
var byteArray:ByteArray = encoder.encode(bitmapData));
// result: byteArray</pre>
<p>URL (image) to ByteArray. Asynchronous operation:</p>
<pre class="brush: as3; title: ; notranslate">import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.net.URLRequest;
import flash.utils.ByteArray;

var loader:Loader = new Loader();
loader.load(new URLRequest(&quot;banner1.jpg&quot;));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderComplete);

private function loaderComplete(event:Event):void
{
    var loaderInfo:LoaderInfo = LoaderInfo(event.target);
    var byteArray:ByteArray = loaderInfo.bytes;
    // result: byteArray
}</pre>
<p>URL (image) to BitmapData. Asynchronous operation:</p>
<pre class="brush: as3; title: ; notranslate">import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.net.URLRequest;
import flash.display.BitmapData;

var loader:Loader = new Loader();
loader.load(new URLRequest(&quot;banner1.jpg&quot;));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderComplete);

private function loaderComplete(event:Event):void
{
    var loaderInfo:LoaderInfo = LoaderInfo(event.target);
    var bitmapData:BitmapData = new BitmapData(loaderInfo.width, loaderInfo.height, false, 0xFFFFFF);
    bitmapData.draw(loaderInfo.loader);
    // result: bitmapData
}</pre>
<p>ByteArray to BitmapData. Asynchronous operation:</p>
<pre class="brush: as3; title: ; notranslate">import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.display.BitmapData;

var loader:Loader = new Loader();
loader.loadBytes(byteArray);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderComplete);

private function loaderComplete(event:Event):void
{
    var loaderInfo:LoaderInfo = LoaderInfo(event.target);
    var bitmapData:BitmapData = new BitmapData(loaderInfo.width, loaderInfo.height, false, 0xFFFFFF);
    bitmapData.draw(loaderInfo.loader);
    // result: bitmapData
}</pre>
<p><a href="http://www.bytearray.org/?p=1089">Synchronous JPEG ByteArray to BitmapData can be found here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2009/10/bitmap-bitmapdata-bytearray/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ActionScript 3 encoding JPEG, alchemy</title>
		<link>http://blog.yoz.sk/2009/10/actionscript-3-encoding-jpeg/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=actionscript-3-encoding-jpeg</link>
		<comments>http://blog.yoz.sk/2009/10/actionscript-3-encoding-jpeg/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 11:53:05 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[alchemy]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[Bitmap]]></category>
		<category><![CDATA[BitmapData]]></category>
		<category><![CDATA[ByteArray]]></category>
		<category><![CDATA[converting]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[jpeg]]></category>
		<category><![CDATA[JPEGEncoder]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=136</guid>
		<description><![CDATA[Lets assume you want to save an image (or any DisplayObject) from flash to disk, or upload to facebook etc. What you need is to encode your BitmapData into an Jpeg and send ByteArray raw data to be saved/uploaded. There are few ways how to do it. First, you can use original adobe mx.graphics.codec.JPEGEncoder. Sadly, [...]]]></description>
			<content:encoded><![CDATA[<p>Lets assume you want to save an image (or any DisplayObject) from flash to disk, or upload to facebook etc. What you need is to encode your BitmapData into an Jpeg and send ByteArray raw data to be saved/uploaded. There are few ways how to do it.</p>
<p>First, you can use original adobe mx.graphics.codec.JPEGEncoder. Sadly, this encoder is the slowest. There were attemps to make it faster by otpimizing code by <a href="http://www.bytearray.org/">bytearray.org</a>, that resulted into two times faster <a href='http://classes.yoz.sk/org/bytearray/images/JPEGEncoder.as'>org.bytearray.images.JPEGEncoder</a>. Usage is pretty simple:</p>
<p><span id="more-136"></span></p>
<pre class="brush: as3; title: ; notranslate">import org.bytearray.JPEGEncoder;

function encode():ByteArray
{
    var bitmapData:BitmapData = new BitmapData(this.width, this.height, false);
    bitmapData.draw(this);
    var encoder:JPEGEncoder = new JPEGEncoder(80);
    return encoder.encode(bitmapData);
}</pre>
<p>But not fast enough <img src='http://blog.yoz.sk/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Since Flash Player 10 introduced <a href="http://labs.adobe.com/technologies/alchemy/">alchemy</a> (compiled C and C++ code within flash apps), it was possible to use <a href='http://classes.yoz.sk/jpegencoder.swc'>optimized C++ encoder to do the work</a>. Encoding time is more than 30 times faster than the original JPEGEncoder, pretty cool huh? Code looks like this</p>
<pre class="brush: as3; title: ; notranslate">import cmodule.jpegencoder.CLibInit;

function encode():ByteArray
{
    var bitmapData:BitmapData = new BitmapData(this.width, this.height, false);
    bitmapData.draw(this);
    var init:CLibInit = new CLibInit();
    var lib:Object = init.init();
    var byteArray:ByteArray = new ByteArray();
    var byteArrayOut:ByteArray = new ByteArray();
    byteArray = bitmapData.getPixels(bitmapData.rect);
    byteArray.position = 0;
    lib.encode(byteArray, byteArrayOut, bitmapData.width, bitmapData.height, 80);
    return byteArrayOut;
}</pre>
<p>You can also run your encoding in asynchronous mode&#8230; Read more and see tests here:</p>
<ul>
<li><a href="http://segfaultlabs.com/blog/post/asynchronous-jpeg-encoding">Alchemy &#8211; asynchronous jpeg encoding</a></li>
<li><a href="http://www.websector.de/blog/2009/06/21/speed-up-jpeg-encoding-using-alchemy/">Speed up JPEG encoding using Alchemy</a></li>
<li><a href="http://labs.adobe.com/technologies/alchemy/">Alchemy technology</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2009/10/actionscript-3-encoding-jpeg/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

