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 );
}
}
}