AS3 Как проверить, пусто ли BitmapData - PullRequest
3 голосов
/ 02 сентября 2011

У меня есть код, чтобы стереть замаскированный мувиклип.(кредиты здесь ) Я хотел бы знать, как я могу проверить, был ли стерт весь клип.Поэтому я подумал, что должен проверить, пусто ли BitmapData, но я мог быть ужасно неправ!Как я могу проверить, были ли удалены все пиксели мувиклипа?
Конечно, мой пример ниже неверен, но я думаю, что это должно быть что-то вроде этого.

if (erasableBitmapData = empty)
    { 
    trace("empty")
    }

    var lineSize:Number=40;
    var doDraw:Boolean=false;
    var resumeDrawing:Boolean=false;

    var erasableBitmapData:BitmapData = new BitmapData(700, 500, true, 0xFFFFFFFF);
    var erasableBitmap:Bitmap = new Bitmap(erasableBitmapData);
    erasableBitmap.cacheAsBitmap = true;
    addChild(erasableBitmap);

    maskee.cacheAsBitmap = true;
    maskee.mask = erasableBitmap;

    var eraserClip:Sprite = new Sprite();
    initEraser();
    function initEraser():void {
        eraserClip.graphics.lineStyle(lineSize,0xff0000);
        eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
    }

    var drawnBitmapData:BitmapData = new BitmapData(700, 500, true, 0x00000000);
    var drawnBitmap:Bitmap = new Bitmap(drawnBitmapData);

    stage.addEventListener(MouseEvent.MOUSE_MOVE,maskMove);
    stage.addEventListener(MouseEvent.ROLL_OUT, maskOut); 
    stage.addEventListener(MouseEvent.ROLL_OVER,maskOver);
    stage.addEventListener(MouseEvent.MOUSE_DOWN,startDrawing);
    stage.addEventListener(MouseEvent.MOUSE_UP,stopDrawing);

    function startDrawing(e:MouseEvent):void {
        eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
        doDraw=true;
    }

    function stopDrawing(e:MouseEvent):void {
        doDraw=false;
        resumeDrawing = false;
    }

    function maskOut(e:Event):void {
        if (doDraw){
            resumeDrawing = true;
        }
    }

    function maskOver(e:MouseEvent):void {
        if (resumeDrawing){
            resumeDrawing = false;
            eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
        }
    }

    function maskMove(e:MouseEvent):void {
        if (doDraw && !resumeDrawing){
            eraserClip.graphics.lineTo(stage.mouseX,stage.mouseY);
            drawnBitmapData.fillRect(drawnBitmapData.rect, 0x00000000); 
            drawnBitmapData.draw(eraserClip , new Matrix(), null, BlendMode.NORMAL);
            erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
            erasableBitmapData.draw(drawnBitmap, new Matrix(), null, BlendMode.ERASE);
        }
            e.updateAfterEvent();
    }


    reset_btn.addEventListener(MouseEvent.CLICK,reset);

    function reset(e:Event):void {
        eraserClip.graphics.clear();
        initEraser();
        erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
    }

Ответы [ 3 ]

6 голосов
/ 02 сентября 2011

Вы можете проверить, возвращает ли getColorBoundsRect прямоугольник с шириной и высотой 0 для цвета, который вы считаете «пустым», установив для аргумента findColor значение false. Есть и другие способы сделать это, но это по крайней мере во много раз быстрее, чем проверка каждого пикселя.

Значение по умолчанию true для аргумента findColor дает вам прямоугольник, который охватывает все пиксели для этих (pixelColor & mask) == emptyColor, true. При работе с альфа-значениями маска 0xFF000000 может использоваться для игнорирования значений rbg пикселя и проверки только его альфа-значения. Таким образом, маска 0xFF000000 и цвет 0xFF000000 будут соответствовать всем полностью непрозрачным пикселям, а маска 0xFF000000 и цвет 0x00000000 будут соответствовать всем полностью прозрачным пикселям. Как указал meddlingwithfire , здесь это не сработает. Если для findColor установлено значение false, этот процесс происходит в обратном порядке, так что прямоугольник будет охватывать все пиксели, которые не , используя пустой цвет. Для растровых изображений, не содержащих других цветов, результатом будет прямоугольник с площадью 0.

var maskColor:uint = 0xFF000000;
var emptyColor:uint = 0x00000000;
var bounds:Rectangle = erasableBitmapData.getColorBoundsRect(maskColor, emptyColor, false);
if (bounds.width == 0 && bounds.height == 0){
    trace("empty"); // no visible pixels
}

Технически существует разница между черным прозрачным пикселем 0x00000000 и, например, красным прозрачным пикселем 0x00FF0000 - но видимой разницы нет (оба невидимы), поэтому вы должны полностью игнорировать значения rgb, как я это сделал в примере с использованием этой конкретной маски.

1 голос
/ 21 апреля 2013

Функция BitmapData.compare(BitmapData) возвращает либо новый BitmapData, содержащий разницу между вызывающими двумя BitmapData s, либо объекты BitmapData эквивалентны (с одинаковой шириной, высотой и одинаковыми значениями пикселей)метод возвращает число 0. Это означает, что вы можете использовать следующее, чтобы проверить, содержит ли DisplayObject графику

var eraseableBitmapData:BitmapData = new BitmapData(264,864,true,0xFFFFFFFF);
//initialise the eraseableBitmapData
eraseableBitmapData.draw(someDisplayOject)
//draw your object's bitmap data

var emptyBitmapData:BitmapData = new BitmapData(264,864,true,0xFFFFFFFF);
//create an identical but empty BitmapData object

if( erasableBitmapData.compare ( emptyBitmapData ) == 0 ) {
    trace("empty");//object is completely empty
} else {
    trace("not empty");//object still has stuff in
}

draw () документации

сравнить () документация

1 голос
/ 02 сентября 2011

Создание базового «пустого» экземпляра BitmapData. Используйте метод сравнения этого BitmapData, передавая ваши «потенциально пустые» BitmapData. Вы получите новую ссылку BitmapData, которая имеет различия в пикселях между ними. Используя эту новую ссылку BitmapData, вы можете получить доступ к методу гистограммы, чтобы получить список всех подсчетов для каждого канала. Если пустой экземпляр BitmapData и «потенциально пустой» экземпляр BitmapData в точности совпадают, то ваш канал гистограммы будет иметь общее количество пикселей в ваших BitmapData в качестве счетчика в нулевом индексе каждого канала (так как в этом случае разница BitmapData равных данных будет заполнено 0x00000000 пикселей).

Также должен быть относительно быстрым, поскольку вы можете полагаться на механизм AS для просмотра каждого пикселя, в отличие от необходимости вручную вызывать дорогой метод getPixel ().

Использование подхода с цветовыми границами может привести к ложным срабатываниям. Если ваши растровые изображения одинаковы в верхнем левом и нижнем левом положениях, то ваш прямоугольник цветовых границ будет охватывать всю область, даже если все промежуточные пиксели могут быть совершенно разными.

...