2012-05-03 65 views
0

我必須構建用於簡單皺紋修飾的Flash應用程序。用戶應該能夠上傳人像照片,選擇起皺的區域,然後模糊濾鏡將應用於選定的部分。我的問題是 - 是否可以將過濾器應用於自由區域?我知道選擇矩形很容易,但這對於真正標記正確的區域並不是很有用。理想情況下,用戶應該使用某種圓形筆刷來標記區域,按「確定」,然後過濾器將被應用。 有沒有辦法做到這一點?你是否可以就如何處理這個任務提供一些進一步的建議?我很少有使用ActionScript處理位圖數據的經驗。在自由區域應用模糊濾鏡

任何幫助表示讚賞!非常感謝預先:-)

Example of how what it should look like..

回答

3

的算法如下:

  1. 使用BitmapData.draw()創建選擇形狀的一個BitmapData(讓它成爲A)
  2. 切一塊長方形的選擇區域覆蓋的原始圖像,使用Bitmapdata.copyPixels()(讓它爲B)爲模糊區域添加一些邊距。
  3. 使用A作爲源位圖,從B中刪除所有未包含在形狀A中的像素BitmapData.threshold()
  4. 模糊產生的圖像
  5. 副本模糊像素背採用Bitmapdata.copyPixels()

目標圖像下面是一個完整和工作的例子。
無論如何,我已經編寫了代碼,同時找出解決方案。
希望你覺得它有用。

package 
{ 
    import flash.display.Bitmap; 
    import flash.display.BitmapData; 
    import flash.display.Loader; 
    import flash.display.Shape; 
    import flash.display.Sprite; 
    import flash.display.StageAlign; 
    import flash.display.StageScaleMode; 
    import flash.events.Event; 
    import flash.filters.BlurFilter; 
    import flash.geom.Matrix; 
    import flash.geom.Point; 
    import flash.geom.Rectangle; 
    import flash.net.URLRequest; 
    import flash.system.LoaderContext; 

    [SWF(width="800", height="600",backgroundColor="#FFFFFF")]  
    public class TestBlur extends Sprite 
    { 
     private const loader:Loader = new Loader(); 

     public function TestBlur() 
     { 
      stage.align = StageAlign.TOP_LEFT; 
      stage.scaleMode = StageScaleMode.NO_SCALE; 

      loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete); 
      loader.load(new URLRequest("http://i.stack.imgur.com/u3iEv.png"), new LoaderContext(true)); 
     } 

     protected function onLoadComplete(event:Event):void 
     { 
      trace(event); 
      var bmp:Bitmap = loader.content as Bitmap; 
      addChild(bmp); 

      // create some test selection area 
      var selection:Shape = new Shape(); 
      selection.graphics.lineStyle(30, 0xFF0000, .5); 
      selection.graphics.curveTo(75, -50, 200, 10); 
      selection.x = 40; 
      selection.y = 60; 
      addChild(selection); 

      // create a duplicate of the original image 
      var target:BitmapData = bmp.bitmapData.clone(); 
      var targetBmp:Bitmap = new Bitmap(target); 
      targetBmp.x = bmp.x + bmp.width; 
      addChild(targetBmp); 

      // 
      // *** main work starts here *** 
      // by now we have selection shape and a bitmap to blur 

      const destPoint:Point = new Point(); 
      const drawMatrix:Matrix = new Matrix(); 
      const blurMargin:uint = 10; 
      const blur:BlurFilter = new BlurFilter(2, 2, 3); 
      var rect:Rectangle; 

      // 0: prepare an image of selection area 
      // we'll need it at step 3 
      rect = selection.getBounds(selection); 
      rect.x -= blurMargin; 
      rect.y -= blurMargin; 
      rect.width += blurMargin*2; 
      rect.height += blurMargin*2;    
      var selectionImage:BitmapData = new BitmapData(rect.width, rect.height, true, 0); 
      drawMatrix.identity(); 
      drawMatrix.translate(-rect.x, -rect.y); 
      selectionImage.draw(selection, drawMatrix); 

        // just some testing 
        var test0:Bitmap = new Bitmap(selectionImage.clone()); 
        test0.y = bmp.y + bmp.height; 
        addChild(test0); 

      // 1: cut a rectangular piece of original image that is covered by selection area 
      rect = selection.getBounds(selection.parent); 
      rect.x -= blurMargin; 
      rect.y -= blurMargin; 
      rect.width += blurMargin*2; 
      rect.height += blurMargin*2; 
      var area:BitmapData = new BitmapData(rect.width, rect.height, true, 0); 
      area.copyPixels(bmp.bitmapData, rect, destPoint); 

        // just some testing 
        var test1:Bitmap = new Bitmap(area.clone()); 
        test1.y = bmp.y + bmp.height; 
        test1.x = test0.x + test0.width; 
        addChild(test1); 

      // 2: remove all pixels that are not covered by selection 
      area.threshold(selectionImage, area.rect, destPoint, "==", 0, 0, 0xFF000000); 

        // just some testing 
        var test2:Bitmap = new Bitmap(area.clone()); 
        test2.y = test0.y + test0.height; 
        test2.x = test0.x; 
        addChild(test2); 

      // 3: blur copied area 
      area.applyFilter(area, area.rect, destPoint, blur); 

        // just some testing 
        var test3:Bitmap = new Bitmap(area.clone()); 
        test3.y = test0.y + test0.height; 
        test3.x = test2.x + test2.width; 
        addChild(test3); 

      // 4: copy blurred pixels back to target image 
      destPoint.x = rect.x; 
      destPoint.y = rect.y; 
      target.copyPixels(area, area.rect, destPoint); 
     }   
    } 
}