In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

flash on 2013-9-6

Basic surface blur

@author Adam Vernon
Get Adobe Flash player
by mark.c.stansberry 06 Sep 2013
    Embed
/**
 * Copyright mark.c.stansberry ( http://wonderfl.net/user/mark.c.stansberry )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/hOAg
 */

// forked from hanenbro_'s Basic surface blur

package {

    import flash.system.LoaderContext;

    

    import flash.net.URLRequest;

    import flash.display.Loader;

    import flash.display.Bitmap;

    import flash.display.BitmapData;

    import flash.display.Sprite;

    import flash.events.Event;

    import flash.filters.BlurFilter;

    import flash.geom.Point;

    import flash.geom.Rectangle;

    

    /**

     * Basic surface blur

     * @author Adam Vernon

     */

    public class SurfaceBlur extends Sprite {

        

        private var _imageLoader:Loader = new Loader();

        private const _imageUrl:String = "http://i.imgur.com/MCGwTPC.jpg";  //Change URL to load a new image

        

        private const _blurAmount:Number = 0.20;                  //Initial blur, seen between detailed areas, value between 0 and 1 (best between 0.02 and 0.2)

        private const _detailProtection:Number = 0.95;            //Degree of detail to bring back, where detail is strongest, value between 0 and 1

        private const _similarityThreshold:Number = 0.000025;     //Min degree of similarity between blurred and original pixel

        

        private var _source:BitmapData;

        private var _blur:BitmapData;

        private var _surface:BitmapData;

        

        private var _sourceBmp:Bitmap;

        private var _blurBmp:Bitmap;

        private var _surfaceBmp:Bitmap;

        

        

        

        public function SurfaceBlur() {

            data_init();

        }

        

        

        //Load image//

        private function data_init():void {

            _imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoader_complete);

            var context:LoaderContext = new LoaderContext(true);

            _imageLoader.load(new URLRequest(_imageUrl), context);

        }

        

        private function imageLoader_complete(evt:Event):void {

            _imageLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, imageLoader_complete);

            _source = (_imageLoader.content as Bitmap).bitmapData;

            

            ui_init();

        }





        //Set up images//

        private function ui_init():void {

            _blur = _source.clone();

            _blur.applyFilter(_blur, new Rectangle(0, 0, _source.width, _source.height), new Point(), new BlurFilter(_blurAmount * 100, _blurAmount * 100, 3));

            surfaceBlur_apply();

            

            _sourceBmp = new Bitmap(_source);

            _blurBmp = new Bitmap(_blur);

            _surfaceBmp = new Bitmap(_surface);

            

            _sourceBmp.smoothing = _blurBmp.smoothing = _surfaceBmp.smoothing = true;

            

            _surfaceBmp.width = _blurBmp.width = _sourceBmp.width = stage.stageWidth;

            _surfaceBmp.height = _surfaceBmp.width * (_surface.height / _surface.width);

            _blurBmp.width = _sourceBmp.width = _surfaceBmp.width * 0.5;

            _blurBmp.height = _sourceBmp.height = _surfaceBmp.height * 0.5;

            _sourceBmp.y = _blurBmp.y = _surfaceBmp.height;

            _blurBmp.x = _blurBmp.width;

            

            addChild(_sourceBmp);

            addChild(_blurBmp);

            addChild(_surfaceBmp);

        }

        

        //***Actual surface blur here***//

        //Iterate over pixels

        private function surfaceBlur_apply():void {

            _surface = _blur.clone();

            var w:int = _source.width;

            var h:int = _source.height;

            

            for (var iW:int = 0; iW < w; iW++) {

                for (var iH:int = 0; iH < h; iH++) {

                    var pSource:uint = _source.getPixel(iW, iH);

                    var pBlur:uint = _blur.getPixel(iW, iH);

                    var similarity:Number = similarity_check(pSource, pBlur);

                    if (similarity < _similarityThreshold) {

                        _surface.setPixel(iW, iH, colour_interpolate(pSource, pBlur, similarity/_similarityThreshold));

                    }

                }

            }

        }

        

        //Compare original and blurred pixel

        private function similarity_check(pSource:uint, pBlur:uint):Number {

            var rSource:uint = pSource >> 16 & 0xFF;

            var rBlur:uint = pBlur >> 16 & 0xFF;

            

            var gSource:uint = pSource >> 8 & 0xFF;

            var gBlur:uint = pBlur >> 8 & 0xFF;

            

            var bSource:uint = pSource & 0xFF;

            var bBlur:uint = pBlur & 0xFF;

            

            return (Math.abs(rBlur - rSource) + Math.abs(gBlur - gSource) + Math.abs(bBlur - bSource)) / 0xFFFFFF;

        }

        

        //Derive new pixel from original and blurred, tempered by similarity and level of detail protection

        private function colour_interpolate(pSource:uint, pBlur:uint, similarity:Number):uint {

            if (_detailProtection == 0) return pBlur;

            

            var rSource:uint = pSource >> 16 & 0xFF;

            var rBlur:uint = pBlur >> 16 & 0xFF;

            var rNew:uint = rBlur + ((rSource - rBlur) * (_detailProtection * similarity));

            

            var gSource:uint = pSource >> 8 & 0xFF;

            var gBlur:uint = pBlur >> 8 & 0xFF;

            var gNew:uint = gBlur + ((gSource - gBlur) * (_detailProtection * similarity));

            

            var bSource:uint = pSource & 0xFF;

            var bBlur:uint = pBlur & 0xFF;

            var bNew:uint = bBlur + ((bSource - bBlur) * (_detailProtection * similarity));

            

            return ( ( rNew << 16 ) | ( gNew << 8 ) | bNew );

        }

        

    }



}