Просмотр полной версии : как узнать что маска заполнена?
Приветствую! Возникла следующая проблема.
Я делаю эффект ластика: есть картинка, на неё накладывается мувик, потом этот мувик стирается пока картинка не будет видна полностью. По сути получается наоборот, я рисую маску через которую видно картинку. Как узнать что картинку полностью видно?
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 угловых пикселей, ну а потом уже все остальные
Как вариант: вместо спрайта в качестве маски используете Bitmap. На битмапдате которого рисуете что-то (либо пиксели (setPixel/setPixel32), либо например любой экранный объект (draw) в качестве кисти). И когда требуется проверка, пробегаетесь по пикселям bitmapData (getPixel/getPixel32). Ну и как вариант (совершенно не обязательно), опять же, вместо маски можно использовать BlendMode.ERASE. По идее проблем будет меньше. Ну и скорее всего есть еще какие-то варианты/вариации.
Хеш байтаррая считайте. Если совпадает с оригинальным... внимание! мы имеем оригинальную BD.
MikroAcse
07.03.2012, 23:16
Хеш байтаррая считайте. Если совпадает с оригинальным... внимание! мы имеем оригинальную BD.
Самая лучшая идея.
BitmapData#getColorBoundsRect() (http://help.adobe.com/ru_RU/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#getColorBoundsRect%28%29)
проверяем на альфу, или на цвет которым закрашивается маска (точнее, на отсутствие цвета))
BitmapData#compare() (http://help.adobe.com/ru_RU/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#compare()) мне кажется лучше это, "Если объекты BitmapData идентичны (имеют одинаковую высоту, ширину и значения пикселей), метод возвращает значение 0." ели ещё перед этим скелить BitmapData основную и текущую то будет значительно быстрее хеша
мне кажется лучше этоЕсли рисуется маска, то для сравнения придется еще и отрисовать результат слияния маски с битмапой перед тем как сравнивать с оригиналом. Или вгонять альфаканал маски в альфаканал исходника, и потом сравнивать. Тогда и для моего и для этого способа надо рисовать маску на битмапдате, а не в векторном шейпе. Не знаю, что будет быстрее - проверить только битмапдату маски на наличие пустот, или скопировать канал и сделать compare().
а можно увидеть какой то пример исходя из моих исходников?
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("+");
}
}
}
Хм. Мой четырехъядерник захлебывается от этого compare().
Помилуйте, "Если два объекта BitmapData имеют одинаковые размеры (ширину и высоту), метод возвращает новый объект BitmapData, в котором каждый пиксел представляет "разницу" между пикселами двух исходных объектов." Это может быть быстро?
А вот так ничо, шустренько.
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 ---");
}
}
}
}
не
if(r.height == 0)
, а так
if(r.isEmpty())
Результат будет другой? Или скорость выше?
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Как Вам нравится все усложнять...
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.