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

Basic surface blur

...
@author Adam Vernon
/**
 * Copyright hanenbro_ ( http://wonderfl.net/user/hanenbro_ )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/Avzz
 */

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/6j4BUMN.jpg";    //Change URL to load a new image
        
        private const _blurAmount:Number = 0.07;                  //Starting 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 );
        }
        
    }

}