Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   как узнать что маска заполнена? (http://www.flasher.ru/forum/showthread.php?t=176336)

Wadimir 07.03.2012 19:47

как узнать что маска заполнена?
 
Приветствую! Возникла следующая проблема.
Я делаю эффект ластика: есть картинка, на неё накладывается мувик, потом этот мувик стирается пока картинка не будет видна полностью. По сути получается наоборот, я рисую маску через которую видно картинку. Как узнать что картинку полностью видно?
Код AS3:

var flag:Boolean = false;
 
var mymask:Sprite = new Sprite();
addChild(mymask);
 
mypic.mask = mymask;
 
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDowns);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMoves);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUps);
 
function onMouseDowns(event:MouseEvent):void
{
        flag = true;
}
 
function onMouseUps(event:MouseEvent):void
{
        flag = false;
}
 
function onMouseMoves(event:MouseEvent):void
{
        if (flag)
        {
                mymask.graphics.beginFill(0x000000);
                mymask.graphics.drawCircle(mouseX, mouseY, 40);
                mymask.graphics.endFill();
        }
}


MikroAcse 07.03.2012 20:46

Есть методы конечно, но это все очень и очень напрягает голову и ЦП, так что забудь :)
Может кто другой подскажет, и мне интересно будет.

ЗлОй ПрОграММер 07.03.2012 21:26

как вариант пройтись по всем пикселям маски и проверить их на прозрачность, ток как реализовать пусть кто нить другой напишет)
причём как только обнаружиться первый не прозрачный пиксель остановить цикл, да ещё б я начал проверку с 4 угловых пикселей, ну а потом уже все остальные

Inet_PC 07.03.2012 22:12

Как вариант: вместо спрайта в качестве маски используете Bitmap. На битмапдате которого рисуете что-то (либо пиксели (setPixel/setPixel32), либо например любой экранный объект (draw) в качестве кисти). И когда требуется проверка, пробегаетесь по пикселям bitmapData (getPixel/getPixel32). Ну и как вариант (совершенно не обязательно), опять же, вместо маски можно использовать BlendMode.ERASE. По идее проблем будет меньше. Ну и скорее всего есть еще какие-то варианты/вариации.

dimarik 07.03.2012 22:21

Хеш байтаррая считайте. Если совпадает с оригинальным... внимание! мы имеем оригинальную BD.

MikroAcse 07.03.2012 23:16

Цитата:

Хеш байтаррая считайте. Если совпадает с оригинальным... внимание! мы имеем оригинальную BD.
Самая лучшая идея.

Wolsh 07.03.2012 23:35

BitmapData#getColorBoundsRect()
проверяем на альфу, или на цвет которым закрашивается маска (точнее, на отсутствие цвета))

Nooob 08.03.2012 03:55

BitmapData#compare() мне кажется лучше это, "Если объекты BitmapData идентичны (имеют одинаковую высоту, ширину и значения пикселей), метод возвращает значение 0." ели ещё перед этим скелить BitmapData основную и текущую то будет значительно быстрее хеша

Wolsh 08.03.2012 12:03

Цитата:

мне кажется лучше это
Если рисуется маска, то для сравнения придется еще и отрисовать результат слияния маски с битмапой перед тем как сравнивать с оригиналом. Или вгонять альфаканал маски в альфаканал исходника, и потом сравнивать. Тогда и для моего и для этого способа надо рисовать маску на битмапдате, а не в векторном шейпе. Не знаю, что будет быстрее - проверить только битмапдату маски на наличие пустот, или скопировать канал и сделать compare().

Wadimir 08.03.2012 14:14

а можно увидеть какой то пример исходя из моих исходников?

Nooob 08.03.2012 23:50

Код AS3:

var flag:Boolean = false;
var brush:Shape = new Shape();
brush.graphics.beginFill(0xFFFFFF);
brush.graphics.drawCircle(20, 20, 20);
 
var brushBitmapData:BitmapData = new BitmapData(40, 40, true, 0);
brushBitmapData.draw(brush);
var alphaBitmapData:BitmapData = new BitmapData(mypic.width, mypic.height, true, 0);
var picBitmapData:BitmapData = new BitmapData(mypic.width, mypic.height, true, 0);
picBitmapData.draw(mypic);
 
var bitmap:Bitmap = new Bitmap(new BitmapData(mypic.width, mypic.height, true, 0));
addChild(bitmap);
 
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDowns);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMoves);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUps);
 
function onMouseDowns(event:MouseEvent):void
{
        flag = true;
}
 
function onMouseUps(event:MouseEvent):void
{
        flag = false;
}
 
function onMouseMoves(event:MouseEvent):void
{
        if (flag)
        {
                alphaBitmapData.copyPixels(brushBitmapData, brushBitmapData.rect, new Point(stage.mouseX - 20, stage.mouseY - 20), null, null, true);
 
                bitmap.bitmapData.fillRect(bitmap.bitmapData.rect, 0);
                bitmap.bitmapData.copyPixels(picBitmapData, picBitmapData.rect, new Point(), alphaBitmapData, new Point(), true);
 
                if(bitmap.bitmapData.compare(picBitmapData) == 0)
                {
                        trace("+");
                }
        }
}


Wolsh 09.03.2012 01:45

Хм. Мой четырехъядерник захлебывается от этого compare().
Помилуйте, "Если два объекта BitmapData имеют одинаковые размеры (ширину и высоту), метод возвращает новый объект BitmapData, в котором каждый пиксел представляет "разницу" между пикселами двух исходных объектов." Это может быть быстро?
А вот так ничо, шустренько.
Код AS3:

package 
{
        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.display.BitmapDataChannel;
        import flash.display.Shape;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import flash.geom.Point;
        import flash.geom.Rectangle;
 
        /**
        * ...
        * @author wolsh
        */

        public class Main extends Sprite
        {
                [Embed(source = "../lib/x_b522d034.jpg")]
                private var _pic:Class;
                private var _imageData:BitmapData;
                private var _image:Bitmap;
                private var _testBitmapData:BitmapData;
                private var _brushBitmapData:BitmapData;
                private var _s:Sprite;
 
                public function Main():void
                {
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
                }
 
                private function init(e:Event = null):void
                {
                        removeEventListener(Event.ADDED_TO_STAGE, init);
                        // entry point
                        _image = new _pic();
                        _imageData = _image.bitmapData;
                        // ПОДЛОЖКА
                        _s = new Sprite();
                        addChild(_s);
                        _s.graphics.beginFill(0x000000);
                        _s.graphics.drawRect(0, 0, _image.width, _image.height);
                        _s.x = 100;
                        _s.y = 50;
                        //// КИСТОЧКА
                        var brush:Shape = new Shape();
                        brush.graphics.beginFill(0x000000);
                        brush.graphics.drawCircle(20, 20, 20);
                        _brushBitmapData = new BitmapData(40, 40, true, 0);
                        _brushBitmapData.draw(brush);
                        //// ОТОБРАЖАЕМАЯ БИТМАПДАТА
                        _testBitmapData = new BitmapData(_image.width, _image.height, true, 0x00000000);
                        var bitmap:Bitmap = new Bitmap(_testBitmapData);
                        addChild(bitmap);
                        bitmap.x = 100;
                        bitmap.y = 50;
                        this.addEventListener(MouseEvent.MOUSE_DOWN, handlerDown);
                }
 
                private function handlerDown(event:MouseEvent):void
                {
                        this.addEventListener(MouseEvent.MOUSE_MOVE, handlerMove);
                        stage.addEventListener(MouseEvent.MOUSE_UP, handlerUp);
                }
 
                private function handlerUp(event:MouseEvent):void
                {
                        this.removeEventListener(MouseEvent.MOUSE_MOVE, handlerMove);
                }
 
                private function handlerMove(event:MouseEvent):void
                {
                        var xMouse:Number = _s.mouseX - 20;
                        var yMouse:Number = _s.mouseY - 20;
                        _testBitmapData.copyPixels(_imageData, new Rectangle(xMouse, yMouse, 40, 40), new Point(xMouse, yMouse), _brushBitmapData, new Point(), true);
                        var r:Rectangle = _testBitmapData.getColorBoundsRect(0xFF000000, 0x00000000, true);
                        if(r.height == 0)
                        {
                                trace("--- END ---");
                        }
                }
 
        }
 
}


Wadimir 09.03.2012 12:24

Цитата:

Сообщение от Wolsh (Сообщение 1067979)

Огромнейшее спасибо!!!

Nooob 09.03.2012 13:06

не
Код AS3:

if(r.height == 0)

, а так
Код AS3:

if(r.isEmpty())


Wolsh 09.03.2012 16:43

Результат будет другой? Или скорость выше?
Код AS3:

package 
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.geom.Rectangle;
 
        /**
        * ...
        * @author wolsh
        */

        public class TimeTest extends Sprite
        {
                private var _counts:uint = 5000000;
 
                public function TimeTest():void
                {
                        // entry point
                        var r:Rectangle = new Rectangle(0, 0, 0, 0);
                        var b:Boolean;
                        var d0:Date = new Date();
                        for (var i:uint = 0; i < _counts; i++)
                        {
                                /* FIRST FIGURANT CODE                    */
                                b = (r.height == 0);
                                /*                                        */
                        }
                        var d1:Date = new Date();
                        for (var j:uint = 0; j < _counts; j++)
                        {
                                /* SECOND FIGURANT CODE                    */
                                b = r.isEmpty();
                                /*                                        */
                        }
                        var d2:Date = new Date();
                        trace("FIRST  : " + (d1.time - d0.time).toString());
                        trace("SECOND : " + (d2.time - d1.time).toString());
                }
 
        }
 
}

Код:

FIRST  : 467
SECOND : 1202

Как Вам нравится все усложнять...


Часовой пояс GMT +4, время: 11:31.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.