Flash / Actionscript 3具有羽化边缘的位图裁剪(模糊边缘)

时间:2011-03-11 01:51:50

标签: flash actionscript-3 bitmap crop

我一直试图找出一个使用Actionscript3执行位图裁剪的好策略。

例如:我有一张汽车的照片,我想单独从图像中裁剪出汽车,并将边缘羽毛化,使它们看起来不会锯齿状。

我是一个闪光菜刀,只用了几个星期。我已经尝试了几个选项,这是我提出的最后一个选项:我在舞台上放置了可以拖动的红点,这样你就可以勾勒出想要裁剪的对象,并且点是一个边界。 gradientFill用作位图的掩码。 (我使用径向渐变...所以结果远非我想要的,因为汽车不是椭圆形的。)

以下是结果图片。(忽略随机黄色虚线椭圆形) GradientFill (radial) used as Bitmap mask

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

问题

1)我怎样才能淡化红点所勾勒出的这种定制形状填充物的边缘?

2)我想在裁剪后将图像保存到文件中。使用BitmapFill或GradientFill作为掩码,这样做的策略会更好(如果两者都可以的话)?

3)我可能正在使用这种策略稍后裁剪人脸..任何人都知道as3的任何良好的面部检测API? (也是边缘检测API)

非常感谢大家:)

1 个答案:

答案 0 :(得分:3)

1)我一直在使用的是创建一个矩形(根据我的需要)但是多边形应该可以工作...... 基本上我创建一个图形应用模糊过滤器并将其用作蒙版。 (而不是使用渐变)

2)查看hype framework,其中有一个类允许您导出图像(tif,png),但还有其他选择。基本上,如果您创建位图并使用绘图功能,则可以使用位图进行导出,

3)你应该看看as3中的haar级联这里有一个链接,其中有很多信息,现在它在as3中相当缓慢,但是谁知道,也许新的molehills api可能会很快改变。 http://web.elctech.com/2009/04/02/using-haar-cascades-and-opencv-in-as3/