0

シンプルなシワのレタッチ用のフラッシュ アプリケーションを作成する必要があります。ユーザーはポートレート写真をアップロードし、しわのある部分を選択すると、選択した部分にぼかしフィルターが適用されます。私の質問は、フィルターをフリーフォーム領域に適用することは何とか可能ですか? 選択範囲を長方形にするのは簡単ですが、正しい領域を実際にマークするにはあまり役に立ちません。理想的には、ユーザーは領域をマークするために使用するある種の丸いブラシを取得する必要があります。[OK] を押すと、フィルターが適用されます。これを行う方法はありますか?また、このタスクに取り組む方法について、さらに推奨事項はありますか? ActionScript を使用してビットマップ データを操作した経験はほとんどありません。

どんな助けでも大歓迎です!事前にどうもありがとう:-)

どのように見えるべきかの例..

4

1 に答える 1

3

アルゴリズムは次のとおりです。

  1. を使用して選択形状の BitmapData を作成しますBitmapData.draw()(A とします)
  2. 選択領域で覆われている元の画像の長方形の部分を切り取り、使用してぼやけた領域にいくつかの余白を追加しBitmapdata.copyPixels()ます(Bとする)。
  3. BitmapData.threshold()Aをソースビットマップとして使用して、形状Aで覆われていないすべてのピクセルをBから削除します。
  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 に答える