开发者

Flash / Actionscript 3 Bitmap crop with feathered edges (blur edges)

I have been trying to figure out a good strategy to perform a bitmap crop using Actionscript3.

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.

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).

Here is a picture of the result.(ignore the random yellow dotted oval)

Flash / Actionscript 3 Bitmap crop with feathered edges (blur edges)

package code{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
impor开发者_开发技巧t 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<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<=rangeX[0])
                rangeX[0]=dotX;
            else if(dotX>rangeX[1])
                rangeX[1]=dotX;
            if(dotY<=rangeY[0])
                rangeY[0]=dotY;
            else if(dotY>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<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<=rangeX[0])
                rangeX[0]=dotX;
            else if(dotX>rangeX[1])
                rangeX[1]=dotX;
            if(dotY<=rangeY[0])
                rangeY[0]=dotY;
            else if(dotY>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;
    }
}
}

Questions

1) How can I fade just the edges of this custom-shaped fill outlined by the red dots?

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)?

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)

Thanks ahead everyone :)


1 ) what I've been using was creating a rectangle (for my needs) but a polygon should work... basically I create a graphic apply the blur filter and use it as mask. (instead of using the gradient)

2 ) have a look at the hype framework, there is one class in there that allow you to export images (tif,png) but there are other choices. Basically if you create a bitmap and use the draw function you can have a bitmap for exporting,

3 ) you should have a look at haar cascades in as3 here's one link with a lot of info for that, it's pretty slow in as3 for now, but who knows, maybe with the new molehills api this might change soon. http://web.elctech.com/2009/04/02/using-haar-cascades-and-opencv-in-as3/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜