THERMOGRAPH

by christian
♥0 | Line 200 | Modified 2017-02-22 03:02:15 | MIT License | (replaced)
play

ActionScript3 source code

/**
 * Copyright christian ( http://wonderfl.net/user/christian )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/SQPl
 */

package
{
    /*
    GUI CONTROLS
    - Fullscreen 
    ( disabled on wonderfl since file explorer exits fullscreen mode )
    - Open Image
    - Save image
    - Effect Range [ 0, 1 ]
    */

    import flash.net.*;
    import flash.geom.*;
    import flash.utils.*;
    import flash.events.*;
    import flash.display.*;
    import flash.system.LoaderContext;

    import com.bit101.components.*;

    /*  @author SPANVEGA // CHRISTIAN  */

    public class THERMOGRAPH extends Sprite
    {
        private var fileFilter : FileFilter = new FileFilter
        (
            'Images (*.jpeg, *.jpg, *.gif, *.png)',
            '*.jpeg; *.jpg; *.gif; *.png;',
            'JPEG; jp2_; GIFF'
        );
        private var file : FileReference;

        private var blend : Number = .50;

        private var source : BitmapData,
                    bitmap : Bitmap,
                    loader : Loader,
                    holder : Sprite,
                    thumb : Thumb;

        private var v : Vector.<uint>,
                    b : BitmapData;

        private var size : int = 150,
                    edge : int = 10;


        public function THERMOGRAPH ()
        {
            with (stage) { scaleMode = 'noScale'; align = 'TL'; frameRate = 30; color = 0xFFFFFF; }

            addChild (bitmap = new Bitmap ());

            gui ();

            //

            file = new FileReference ();

            file.addEventListener (Event.SELECT, select);
            file.addEventListener (Event.COMPLETE, load);

            //

            loader = new Loader ();

            loader.contentLoaderInfo.addEventListener (Event.COMPLETE, setup);
            loader.load (new URLRequest
            ('http://assets.wonderfl.net/images/related_images/9/9c/9c47/9c4770567ae4d1206aed53aa9ed92504eacc3ef4'),
                         new LoaderContext (true));

            //

            stage.addEventListener (Event.RESIZE, function () : void
            {
                setup ();

                holder.y = stage.stageHeight - 30;
            });
        }

        private function setup (e : Event = null) : void
        {
            if (e) // update source
            {
                source = e.target.content.bitmapData;
            }

            var ratio : Number = 1.0,

                w : int = source.width,
                h : int = source.height;

            if (w > stage.stageWidth || h > stage.stageHeight)
            {
                var rw : Number = stage.stageWidth  / w,
                    rh : Number = stage.stageHeight / h;

                ratio = rw < rh ? rw : rh;
            }

            b = new BitmapData (w * ratio, h * ratio, false, 0xFFFFFF);

            b.drawWithQuality (source, new Matrix (ratio, 0, 0, ratio), null, null, null, true, StageQuality.HIGH_16X16);

            v = b.getVector (b.rect);

            bitmap.bitmapData = b;

            //

            var thumb_w : int = w > h ? size : size * (w / h),
                thumb_h : int = w > h ? size * (h / w) : size;

            if (e) // update thumb
            {
                var data : BitmapData = new BitmapData (thumb_w + 2, thumb_h + 2, false, 0xFFFFFF);
        
                data.drawWithQuality (source, new Matrix (thumb_w / w, 0, 0, thumb_h / h, 1, 1), null, null, null, true, StageQuality.HIGH_16X16);

                if (! thumb) thumb = new Thumb ();

                thumb.vector = data.getVector (data.rect);

                thumb.rectangle = new Rectangle (0, 0, thumb_w + 2, thumb_h + 2);

                data.dispose ();
            }

            thumb.rectangle.x = b.width  - (edge + thumb_w + 1);
            thumb.rectangle.y = b.height - (edge + thumb_h + 1);

            //

            render ();
        };

        private function calc (i : Vector.<uint>) : Vector.<uint> 
        {
            var n : int = i.length,

                o : Vector.<uint> = new Vector.<uint>(n, true);

            while (--n > -1)
            {
                var color : uint = i [n],

                    red : Number = 0, green : Number = 0, blue : Number = 0;

                // http://level0.kayac.com/2010/10/pixelbender_thermograph.php

                var luminance : Number = ((color >> 16 & 0xFF) * 0.29891 +
                                          (color >> 8  & 0xFF) * 0.58661 +
                                          (color       & 0xFF) * 0.11448) / 0xFF;

                if (luminance < 1.0 / 6.0)
                {
                    blue = luminance * 6.0;
                }
                else if (luminance < 2.0 / 6.0)
                {
                    blue = 1.0;
                    green = luminance * 6.0 - 1.0;
                }
                else if (luminance < 3.0 / 6.0)
                {
                    green = 1.0;
                    blue = 3.0 - luminance * 6.0;
                }
                else if (luminance < 4.0 / 6.0)
                {
                    green = 1.0;
                    red = luminance * 6.0 - 3.0;
                }
                else
                {
                    red = 1.0;
                    green = 3.0 - luminance * 3.0;
                }

                o [n] = lerp32bits
                (
                    color, 0xFF << 24 | red * 0xFF << 16 | green * 0xFF << 8 | blue * 0xFF, blend
                );
            }

            return o;
        }

        private function lerp32bits (a : uint, b : uint, p : Number) : uint
        {
            return lerp (a >> 24 & 0xFF, b >> 24 & 0xFF, p) << 24 |
                   lerp (a >> 16 & 0xFF, b >> 16 & 0xFF, p) << 16 |
                   lerp (a >> 8  & 0xFF, b >> 8  & 0xFF, p) <<  8 |
                   lerp (a       & 0xFF, b       & 0xFF, p);
        }

        private function lerp (a : Number, b : Number, p : Number) : Number
        {
            return a + (b - a) * p;
        }

        private function render () : void
        {
            b.setVector (b.rect, calc (v));

            b.setVector (thumb.rectangle, thumb.vector);
        }

        private function gui () : void
        {
            with (Style) { BACKGROUND = LABEL_TEXT = DROPSHADOW = 0xFFFFFF; BUTTON_FACE = 0x0; BUTTON_DOWN = 0x404040; }

            holder = new Sprite ();

            holder.graphics.beginFill (0x0, 0.35);

            holder.graphics.drawRect (0, 0, 253, 30);

            holder.y = stage.stageHeight - holder.height;

            with (new PushButton (holder, 5, 5, '+', screen))   { width = 15; draw (); enabled = false; }

            with (new PushButton (holder, 25, 5, 'OPEN', open)) { width = 50; draw (); }

            with (new PushButton (holder, 80, 5, 'SAVE', save)) { width = 50; draw (); }

            with (new HUISlider (holder, 126, 1, null)) { width = 150; labelPrecision = 2; setSliderParams (0, 1, blend); tick = 0.05;

                addEventListener (Event.CHANGE, update);
            }

            addChild (holder);
        }

        private function update (e : Event) : void
        {
            blend = Number (e.target.value);

            render ();
        }

        private function screen (e : Event) : void
        {
            if (stage.displayState == StageDisplayState.NORMAL)
            {
                stage.displayState = StageDisplayState.FULL_SCREEN;

                e.target.label = 'x';
            }
            else
            {
                stage.displayState = StageDisplayState.NORMAL;

                e.target.label = '+';
            }
        }

        private function open (e : Event) : void
        {
            file.browse ([fileFilter]);
        }

        private function select (e : Event) : void
        {
            file.load ();
        }

        private function load (e : Event) : void
        {
            loader.loadBytes (file.data);
        }

        private function save (e : Event) : void
        {
            var data : ByteArray = new ByteArray (),

                temp : BitmapData = source.clone ();

            temp.setVector (temp.rect, calc (source.getVector (temp.rect)));

            temp.encode (temp.rect, new PNGEncoderOptions (false), data);

            new FileReference ().save (data, ('THERMO_' + getTimer ()) + '.png');
        }
    }
}

import flash.geom.Rectangle;

class Thumb
{
    public var rectangle : Rectangle,

               vector : Vector.<uint>;
}