2011-03-11 93 views
2

我一直在试图找出一个使用Actionscript3来执行位图裁剪的好策略。Flash/Actionscript 3带有羽化边缘的位图裁剪(模糊边缘)

例如:我有一张汽车的图片,我想从图像中挖出汽车并羽化边缘,使它们看起来没有锯齿。

我是一个flash noob,只用了几个星期。我已经尝试了几个选项,下面是我提出的最后一个选项:我在可拖动的舞台上放置红色点,以便可以勾勒出要裁剪的对象,并且点是界限用作位图掩码的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)提前

谢谢大家:)

+0

+1的独创性。 – alxx 2011-03-11 08:18:59

回答

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/

+0

非常感谢,效果很好,另一个问题出现了:我如何从MovieClip获得一个掩码到一个位图? – tjmehta 2011-03-11 04:32:27

+2

'bitmapData.draw(clip)' – alxx 2011-03-11 08:20:21