0

我必须为简单的皱纹修饰构建一个 Flash 应用程序。用户应该能够上传肖像照片,选择皱纹区域,然后将模糊过滤器应用于所选部分。我的问题是 - 是否有可能将过滤器应用于自由形状区域?我知道将选择设为矩形很容易,但这对于真正标记正确的区域并不是很有用。理想情况下,用户应该使用某种圆形刷子来标记区域,按“确定”,然后将应用过滤器。有没有办法做到这一点?对于如何完成这项任务,您可能有一些进一步的建议吗?我对使用 ActionScript 操作位图数据的经验很少。

任何帮助表示赞赏!首先十分感谢 :-)

它应该是什么样子的示例..

4

1 回答 1

3

算法如下:

  1. 使用创建一个选择形状的 BitmapData BitmapData.draw()(让它成为 A)
  2. 剪切一块被选择区域覆盖的矩形原始图像,使用Bitmapdata.copyPixels()(让它成为B)为模糊区域添加一些边距。
  3. BitmapData.threshold()使用 A 作为源位图,从 B 中删除所有未被形状 A 覆盖的像素。
  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);
        }        
    }
}
于 2012-05-03T11:52:31.393 回答