<?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>Thu, 09 Sep 2010 14:00:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Pixel Bender Disco</title>
		<link>http://blog.yoz.sk/2010/02/pixel-bender-disco/?utm_source=rss&amp;utm_medium=rss&amp;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) &#60;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&#62; &#60;mx:Application xmlns:mx=&#34;http://www.adobe.com/2006/mxml&#34; layout=&#34;absolute&#34; enterFrame=&#34;enterFrame()&#34; [...]]]></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;">&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;">&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;">&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;">&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&amp;utm_medium=rss&amp;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;">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&amp;utm_medium=rss&amp;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;">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;">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;">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>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2010/01/how-to-resize-an-image-with-actionscript/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Frame rate optimization</title>
		<link>http://blog.yoz.sk/2009/11/frame-rate-optimization/?utm_source=rss&amp;utm_medium=rss&amp;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;">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;">&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&amp;utm_medium=rss&amp;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;): import flash.display.BitmapData; [...]]]></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;">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;">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;">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;">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;">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;">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>1</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&amp;utm_medium=rss&amp;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;">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;">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>
