Note that there are some explanatory texts on larger screens.

plurals
  1. POFlash / Actionscript 3 Bitmap crop with feathered edges (blur edges)
    text
    copied!<p>I have been trying to figure out a good strategy to perform a bitmap crop using Actionscript3. </p> <p>For example: I have a picture of a car and I want to crop out the car from the image alone and feather the edges so that they do not look jagged. </p> <p>I am a flash noob and have only been using it for a couple of weeks. I've tried a couple of options and here is the last one that I have come up with it: I place red dots on stage that are draggable so that you can outline the object you want to crop and the dots are the bounds for a gradientFill that is used as the bitmap's mask. (I am using a radial gradient ... so the results are far from what I want, since the car is not an oval).</p> <p><em>Here is a picture of the result.</em>(ignore the random yellow dotted oval) <img src="https://i.stack.imgur.com/ALzj9.png" alt="GradientFill (radial) used as Bitmap mask"></p> <pre><code>package code{ import flash.display.Sprite; import flash.display.Bitmap; import flash.display.BitmapData; import flash.events.Event; import flash.events.MouseEvent; //import flash.display.Graphics; import fl.controls.Button; import code.CropDot; import flash.display.MovieClip; import flash.display.GradientType; import flash.display.SpreadMethod; import flash.geom.Matrix; import flash.display.Shape; //import fl.controls.RadioButton; public class BitmapEdit extends Sprite{ public var maskee:MovieClip; public var bitmap:Bitmap; public var dots:Sprite; public var fill:MovieClip; public var numDots:int; public var circ:Shape = new Shape(); //////////////////// public var mat:Matrix=new Matrix(); public var circRad:Number=50; public var offsetX:int; public var offsetY:int; public function BitmapEdit(bmp:Bitmap){ trace("bitmapedit"); //MASK Stuff //-------------- bitmap = new Bitmap(bmp.bitmapData); maskee = new MovieClip(); maskee.addChild(bitmap); fill = new MovieClip(); this.addChild(maskee); this.addChild(fill); maskee.mask = fill; maskee.cacheAsBitmap = true; fill.cacheAsBitmap = true; // DOTS DOTS DOTS //--------------- dots = new Sprite(); numDots = 12; offsetX = 90; offsetY = 90; cX = dot0.x+offsetX; cY = dot0.y+offsetY; rangeX = [cX,cX]; rangeY = [cY,cY]; for(var i:int=0;i&lt;numDots;i++){ this['dot'+i.toString()].x += offsetX; this['dot'+i.toString()].y += offsetY; //this['dot'+i.toString()].name = 'dot'+i.toString(); dots.addChild(this['dot'+i.toString()]) cX+=dotX; cY+=dotY; if(dotX&lt;=rangeX[0]) rangeX[0]=dotX; else if(dotX&gt;rangeX[1]) rangeX[1]=dotX; if(dotY&lt;=rangeY[0]) rangeY[0]=dotY; else if(dotY&gt;rangeY[1]) rangeY[1]=dotY; } cdot.x = cX; cdot.y = cY; this.addChild(dots); fill.graphics.lineStyle(3,0,1.0,true); this.addEventListener(Event.ENTER_FRAME, enterFrameHandler); } public var cX:Number; public var cY:Number; public var dotX:Number; public var dotY:Number; public var prevdotX:Number; public var prevdotY:Number; public var rangeX:Array; public var rangeY:Array; protected function enterFrameHandler(e:Event){ //draw lines between dots this.setChildIndex(fill,this.numChildren-2); this.setChildIndex(dots,this.numChildren-1); fill.graphics.clear(); //-Draw Fill var fW = rangeX[1]-rangeX[0]; var fH = rangeY[1]-rangeY[0]; mat.createGradientBox(fW, fH, 0, cX-fW/2, cY-fH/2); //fill.graphics.beginFill(0,1); //fill.graphics.beginBitmapFill(bitmap.bitmapData); //mat = new Matrix(); //fill.graphics.beginFill(0,1); fill.graphics.beginGradientFill(GradientType.RADIAL,[0x000000, 0x000000], [1, 0], [123,255], mat, SpreadMethod.PAD, "rgb", 0); fill.graphics.moveTo(dot0.x, dot0.y); cX = dot0.x; cY = dot0.y; prevdotX = dot0.x; prevdotY = dot0.y; rangeX = [cX,cX]; rangeY = [cY,cY]; for(var i:int=1; i&lt;numDots; i++){ dotX = this['dot'+i.toString()].x; dotY = this['dot'+i.toString()].y; fill.graphics.lineTo( dotX, dotY); cX+=dotX; cY+=dotY; if(dotX&lt;=rangeX[0]) rangeX[0]=dotX; else if(dotX&gt;rangeX[1]) rangeX[1]=dotX; if(dotY&lt;=rangeY[0]) rangeY[0]=dotY; else if(dotY&gt;rangeY[1]) rangeY[1]=dotY; } cX/=numDots; cY/=numDots; //trace("ctr:"+cX+","+cY); cdot.x = cX; cdot.y = cY; fill.graphics.lineTo(dot0.x,dot0.y); // */ //EndFill fill.graphics.endFill(); } function toRad(a:Number):Number { return a*Math.PI/180; } } } </code></pre> <p><strong>Questions</strong></p> <p>1) How can I fade just the edges of this custom-shaped fill outlined by the red dots?</p> <p>2) I want to save the image out to a file once it's cropped. What strategy would be better for doing this using a BitmapFill or a GradientFill as a Mask (If it's possible with both)?</p> <p>3) I may be using this strategy to crop faces later on.. anyone know of any good face detection APIs for as3? (also edge detection APIs)</p> <p>Thanks ahead everyone :)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload