Определение размера клипа с учетом эффектов

Поскольку тренд физических паззлов я пропустил мимо ушей, попытаюсь попасть хотя бы в тренд кэширования мувиклипов в растр. ;)

Хочу поделиться приемом, который позволяет достоверно узнать габариты клипа с учетом примененных фильтров (только симметричных типа glow и blur, возможное смещение в shadow не учитывается). Моя реализация рассчитана на AS 2, но, для третьего, я думаю, она тоже подойдет, тут главный прикол в принципе, а он прост:

1) получаем список фильтров (var arFilters = this.filters)
2) применяем эти фильтры к битмапе 1х1 пиксель
3) получаем размер битмапы с учетом примененных фильтров
4) добавляем этот новый размер к оригинальному размеру клипа.

В качестве бонуса прикладывается учет трансформации клипа — вращение и масштабирование, но получение полного размера клипа происходит до комментария "// apply transformations", дальше идет применение трансформаций.

Сам исходник, напоминаю, это AS 2:
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Matrix;

var mc = MovieClip.prototype;

mc.screenshotAsIs = function (){
                        
        var b = this.getBounds(this._parent);
        
        var w = b.xMax - b.xMin;
        var h = b.yMax - b.yMin;
        
        ///////////////////////////////////////////////////////
        // find all filters which can enlarge width and height
        ///////////////////////////////////////////////////////
        
        var arFilters = this.filters;
        
        if (arFilters.length){
                
                var rect;
                var bmp         = new BitmapData(1, 1, false, 0x000000);
                
                var wMargin     = 0;
                var hMargin     = 0;
                
                for (var i=0; i<arFilters.length; i++){
                                        
                        rect    = new Rectangle (0, 0, 1, 1);
                        rect    = bmp.generateFilterRect(rect, arFilters[i]);
                        
                        wMargin += (rect.width-1) / 2;
                        hMargin += (rect.height-1) / 2;
                                                
                }
                bmp.dispose();          
                
                // correct movieclip's width, height and bounds
                
                w += wMargin * 2;
                h += hMargin * 2;
                
                b.xMin -= wMargin;
                b.xMax += wMargin;
                b.yMin -= hMargin;
                b.yMax += hMargin;
                
        }


        // create bitmap

        w = Math.round(w);
        h = Math.round(h);

        var bmp = new BitmapData (w, h, true, 0);
        
        
        
        // apply transformations
        
        var rotation = this._rotation;
        this._rotation = 0;

        var mX  = this._x - b.xMin;
        var mY  = this._y - b.yMin;
        
        var matrix      = new Matrix();
        matrix.scale (this._xscale/100, this._yscale/100);
        matrix.rotate (rotation/RAD);
        matrix.translate (mX, mY);
        
        
        // make screenshot
        
        bmp.draw(this, matrix, undefined, 'normal', undefined, true);   
                
        bmp.xShift      = this._x - b.xMin;
        bmp.yShift      = this._y - b.yMin;
        
        
        // restore original rotation and return bitmap
        
        this._rotation = rotation;
        
        return bmp;
        
}


Спасибо всем за внимание, а EugeneYailenko за приглашение. :)

Комментарии (20)

+1
Прикольный прием. Я не стал с этим маяться, как и с попытками выцеплять маски. Потому что в общем случае их надо искать во всей иерархии. С масками все просто обходится. А с фильтрами…

Дело в том, что я себя не ограничиваю при рисовании, то-есть, как я раньше писал, будучи не проф. художником приходится изгаляться. В итоге вид травы из космоса может быть фильтром над векторной текстурой с разводами, на которой еще сверху линии со выкрученным стилем hatched и потом еще один фильтр. А аналогично анимация, скажем метеоритного дождя может состоять из нескольких метеоритов, каждый из которых внутри тоже фильтр имеет. То-есть вариантов, когда фильтры наложены только на конечный мувиклип, у меня нет.

Да, кстати,… бросай АС2 и всплывай поскорее! © :)
0
Да, и в моем классе если надо можно обойтись и с фильтрами. Просто поскольку жоско не сталкивался — не стал делать.
А сделать просто — надо заложиться на то, что фильтр не может скажем на 256 пискелей в стороны уйти за границу. Ибо это чудовищьный фильтр :). И рендерить в черновую битмапдату сразу с запасом. А потом обрезка все равно лишнее обрежет. И все.
0
getColorBoundsRect — это классная штука, вне всякого сомнения, просто ты написал про изящность определения размера наложенных фильтров, ну я и подумал, что использование нативного флэшевого движка для этого как раз такой вариант. :)

А насчет AS 3 — сейчас в срочном порядке запилю игру про зомбей, и если не будет полным фейлом, то займусь переходом, есть у меня определенная проблема с этим, но, конечно, новые возможности и производительность манят уже давно…
0
Пойду поменяю пару цифр в своем классе, раз оказывается кому-то нужно и с фильтрами иметь дело.
0
и если не будет полным фейлом, то займусь переходом
Переходи по любому, AS3 — это здорово! :)
Когда его освоишь, будешь говорить — почему я раньше не перешел?
+2
Я дык вообще удивляюсь, как люди до сих пор сидят на AS2? Он убог и неудобен. Да и подумайте, AS3 вышел в 2007-м! За 4 года уж надо было перейти-то:) Совет:
Мой переход произошёл в поезде, при чтении книги O'Reilly «Action Script 3.0. Сборник рецептов».
Т.е. даже компа не было рядом:)
0
Я дык вообще удивляюсь, как люди до сих пор сидят на AS2? Он убог и неудобен.
Что удобнее, машина или экскаватор? По-моему, для поездок на дачу экскаватор не удобен, а для копания земли неудобна легковушка. :)

Шире смотрите на вещи, AS 2 и AS 3 просто разные.
0
Не провоцируйте холивар )

А если серьезно, каждый пишет как ему удобно. Мы ведь взрослые люди.
0
Самое главное, я думаю, человек должен понимать разницу между AS2 и AS3, и почему он выбирает тот или иной. А не просто писать на AS* потому что об этом была его первая книга.
0
А что из AS2 и AS3 экскаватор и легковушка? :)
0
Я против навешивания ярлыков. :)
0
Разные вещи?.. Да, разные. Только я б сказал, что AS3 — это дорогая иномарка, а AS2 — это автомобиль «Ока». Разница примерно такая:)
0
Ок.
0
при чтении книги O'Reilly «Action Script 3.0. Сборник рецептов».
+1, переходить на ас3 на ней гораздо легче чем по муку! книга специально под это заточена, и гораздо читабельнее. Всё время встречаются конструкции типа «вот такто было в ас2, а в ас3 — так.»
0
Согласен. Я читал и Колина Мука и «Сборник рецептов», видно не одному мне показалось, что «Сборник рецептов» гораздо понятнее.
0
Однозначно… Мук как-то после сборника даже не понадобился:)
0
Ну вот например. Мне нужно сделать презентацию или слайдшоу, мб простенькую игру. Как ты думаешь, какой язык я выбиру?:)
+3
Не вижу проблем выбрать AS3, не сложнее и затрат по времени столько же.
Выбор AS2 в данном случае дело привычки, как мне кажется.
0
Совершенно верно!:) Больше никаких аргументов вы здесь не найдёте ^_^
+2
написал пост о том как сменить шину, все стали рассказывать как им помогла книга Аллена Карра «Легкий способ бросить курить»
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.