Получить BitmapData из displayObject, включая прозрачную область и область эффекта

У меня есть такая функция:

    public static function cloneDpObj(target:DisplayObject):Bitmap
    {
        var duplicate:Bitmap;

        var tBitData:BitmapData = new BitmapData(target.width, target.height);
        tBitData.draw(target);
        duplicate = new Bitmap(tBitData);

        return duplicate;
    }

для клонирования целевого displayObject (MovieClip или Sprite) и возврата Bitmap Object.

Он может получить растровое изображение из целевого объекта, но, похоже, не получает всю область изображения.

Указав ширину и высоту целевого объекта, но целевой объект в дизайне был применен с помощью эффекта свечения, поэтому мой вопрос, можем ли мы получить все представление растровых данных из отображаемого объекта?


person Ratha Hin    schedule 05.08.2011    source источник
comment
Вы пытались получить размеры методом DisplayObject.getBounds вместо width и height? Кроме того, название вашей функции cloneDpObj вводит в заблуждение - она ​​не клонирует DisplayObject, в лучшем случае клонирует свое растровое изображение, хотя я бы сказал, что он просто отображает его в новый Bitmap. Клонирование имеет довольно четко определенное значение в контексте, в котором люди будут читать ваш код.   -  person amn    schedule 05.08.2011


Ответы (4)


BitmapData.draw() делает снимок заданного объекта, удаляя все преобразования и фильтры, примененные в рабочей области. Полученное изображение показывает объект в том виде, в котором он присутствует в вашей библиотеке фильмов.

Есть два основных варианта рисования экранных объектов с преобразованиями и / или фильтрами.

  1. Вы можете применить все преобразования во время рисования с параметром матрицы для BitmapData.draw(). После рисования вы можете применить фильтры к результирующему растровому изображению с помощью BitmapData.applyFilter().
  2. Просто нарисуйте родительский контейнер, а не сам объект.

Я обычно выбираю последнее. Это довольно просто. Есть некоторые недостатки: если вы выберете второй метод, ваша цель должна иметь родительский список отображения, и вы можете рисовать нежелательный контент, который находится в родительском контейнере. (Однако эти недостатки легко устраняются.)

// bounds and size of parent in its own coordinate space
var rect:Rectangle = target.parent.getBounds(target.parent);
var bmp:BitmapData = new BitmapData(rect.width, rect.height, true, 0);

// offset for drawing
var matrix:Matrix = new Matrix();
matrix.translate(-rect.x, -rect.y);

// Note: we are drawing parent object, not target itself: 
// this allows to save all transformations and filters of target
bmp.draw(target.parent, matrix);
person Michael Antipin    schedule 05.08.2011

Вам нужно вычислить площадь / прямоугольник вашего DisplayObject, включая площадь, занимаемую примененным фильтром. К счастью, вы можете сделать это с помощью встроенных функций, используя generateFilterRect () класса BitmapData.

Кроме того, по другим причинам, если вам нужно преобразование вашего DisplayObject, примененное к моментальному снимку BitmapData, вы можете передать исходный DisplayObject .transform. concatenatedMatrix в качестве второго параметра метода draw () BitmapData.

person George Profenza    schedule 05.08.2011

Большое спасибо всем, кто нашел драгоценное время, ответив на мой вопрос. Я улучшил эту функцию, но стал лучше, но я заметил, что ширина результата захвата составляет смещение в 1 пиксель, поэтому я решил добавить 1 пиксель к ширине растровых данных, я знаю, что это не очень хорошая практика. потому что я должен сделать это сейчас, я еще не знаю, в чем проблема. Вот как наша функция сейчас:

 public static function cloneDpObj(target:DisplayObject, optWidth:Number = -1, optHeight:Number = -1):Bitmap
    {
        var duplicate:Bitmap;

        if (!target.parent) {
            var tempSprite:Sprite = new Sprite;
            tempSprite.addChild(target);
        }

        var rect:Rectangle = target.parent.getBounds(target.parent);
        var bmp:BitmapData = new BitmapData(rect.width + 1, rect.height, true, 0);

        // offset for drawing
        var matrix:Matrix = new Matrix();
        matrix.translate( -rect.x, -rect.y);

        // Note: we are drawing parent object, not target itself: 
        // this allows to save all transformations and filters of target
        bmp.draw(target.parent, matrix);

        duplicate = new Bitmap(bmp);

        return duplicate;
    } 
person Ratha Hin    schedule 08.08.2011

На самом деле я бы выбрал первый вариант Nox как более простой подход, и для изменения вашей функции для этого потребуется всего одна дополнительная строка кода:

public static function cloneDpObj(target:DisplayObject):Bitmap
{
    var duplicate:Bitmap;

    var tBitData:BitmapData = new BitmapData(target.width, target.height);
    tBitData.draw(target);
    duplicate = new Bitmap(tBitData);
    //add the filters
    duplicate.filters = target.filters;

    return duplicate;
}
person shanethehat    schedule 05.08.2011
comment
Что ж, это вариант, но вы также должны что-то сделать с областью изображения. Копирование преобразований в любом случае требует использования матрицы и перевода. Я думаю, что это сложнее, чем просто нарисовать родительский объект. - person Michael Antipin; 05.08.2011
comment
Большое спасибо всем, кто нашел драгоценное время, ответив на мой вопрос. Я улучшил эту функцию, но стал лучше, но я заметил, что ширина результата захвата составляет смещение в 1 пиксель, поэтому я решил добавить 1 пиксель к ширине растровых данных, я знаю, что это не очень хорошая практика. потому что я должен сделать это сейчас, я еще не знаю, в чем проблема. Вот как наша функция сейчас: - person Ratha Hin; 08.08.2011