2011-03-11 131 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