ColorMatrixFilter и ConvolutionFilter могут использоваться для визуального преобразования ваших объектов Flash. В этой статье я покажу вам, как легко ими манипулировать, используя классный инструмент, который я создал для простых экспериментов.
Вступление
Ребята, вы когда-нибудь экспериментировали с фильтрами ColorMatrix и Convolution от Flash? Я копался в квесте, чтобы найти интересные вещи, которые можно сделать с помощью Flash, и наткнулся на них. Экспериментируя с ними, можно получить удивительные результаты.
Я написал EffectsTester, чтобы было легко экспериментировать с ними. Посмотрите на эти камшоты, которые я сделал, играя с ним:
Теперь, если вам это интересно, позвольте мне рассказать вам о том, что представляют собой эти два фильтра.
Цветовой матричный фильтр
Фильтр цветовой матрицы используется для управления цветом экранного объекта.
Позвольте мне объяснить точный расчет, выполненный ColorMatrixFilter. Каждый пиксель в изображении представляет собой смесь красного, зеленого и синего. Эти основные цвета , когда объединены, могут сделать любой другой цвет:
Изображение из Wikimedia Commons. Спасибо Майку Хорвату и якоболусу.
Количество красного в пикселе может варьироваться от нуля (вообще никакого красного) до 255. То же самое для зеленого и синего. Итак, на изображении выше вы можете видеть, что чистый желтый пиксель имеет красный = 255, а зеленый = 255. Белый имеет красный, зеленый и синий, все настроены на 255. У черных все три установлены на ноль.
Фильтр цветовой матрицы просматривает каждый пиксель исходного изображения и меняет их в зависимости от того, сколько красного, синего и зеленого в пикселе. Вы получаете совершенно новый образ; целевое изображение .
Вот как это работает
Во-первых, давайте сосредоточимся на этих трех значениях:
Давайте по очереди обозначим эти значения a [0], a [1] и a [2]. Теперь подумайте только об одном пикселе во всем исходном изображении (подойдет тот, который находится в верхнем левом углу). Давайте назовем количество красного в этом srcR , количество зеленого srcG и количество синего srcB .
Вопрос в том, сколько красного будет в этом пикселе конечного изображения, destR ? Flash использует этот расчет:
1
|
destR = ( a[0] * srcR ) + ( a[1] * srcG ) + ( a[2] * srcB );
|
Здесь вы можете видеть, что a [0] равно 1, а a [1] и a [2] равны нулю, поэтому:
1
2
3
|
destR = ( 1 * srcR ) + ( 0 * srcG ) + ( 0 * srcB );
//which means…
destR = srcR;
|
Там нет изменений! Но что если мы изменили a [0] на ноль и a [1] на 1? Потом:
1
2
3
|
destR = ( 0 * srcR ) + ( 1 * srcG ) + ( 0 * srcB );
//which means…
destR = srcG;
|
… количество красного в целевом пикселе будет равно количеству зеленого в исходном пикселе! Кроме того, если вы изменили вторую строку на «1 0 0» , то количество зеленого в целевом пикселе будет равно количеству красного в исходном пикселе; вы бы поменяли их местами, и ваша оранжевая рыба превратилась бы в зеленую:
Вы, вероятно, задаетесь вопросом о столбце A и строке и о столбце Offset . Ну, А означает альфа, что означает прозрачность. Значения A имеют почти такой же эффект, как и значения RGB, но поскольку ни одно из этих образцов изображений не является прозрачным, продемонстрировать это сложно. Столбец «Смещение» позволяет просто увеличивать или уменьшать количество красного, синего или зеленого в целевом пикселе: введите -255 в столбце «Смещение» строки R, и вы увидите, что на изображении больше нет красного.
эксперимент
Я понимаю, что это сложно понять, просто прочитав об этом, поэтому мы рассмотрим некоторые интересные примеры эффектов. В любом случае, это намного веселее. Но сначала, для любопытства, вот фактическая математическая формула, которую использует Flash:
1
2
3
4
|
destR = ( a[0] * srcR ) + ( a[1] * srcG ) + ( a[2] * srcB ) + ( a[3] * srcA ) + a[4];
destG = ( a[5] * srcR ) + ( a[6] * srcG ) + ( a[7] * srcB ) + ( a[8] * srcA ) + a[9];
destB = ( a[10] * srcR ) + ( a[11] * srcG ) + ( a[12] * srcB ) + ( a[13] * srcA ) + a[14];
destA = ( a[15] * srcR ) + ( a[16] * srcG ) + ( a[17] * srcB ) + ( a[18] * srcA ) + a[19];
|
(Каждое из значений, которые вы видите в матрице 5×4, может варьироваться от -255 до 255.)
Взгляните на образец изображения «Color Chart»:
Теперь предположим, что вы хотите удалить весь красный цвет с картинки. Просто установите все значения в строке R на ноль:
Это означает:
1
2
3
4
5
|
destR = ( 0 * srcR ) + ( 0 * srcG ) + ( 0 * srcB ) + ( 0 * srcA ) + 0;
//which means:
destR = 0 + 0 + 0 + 0 + 0;
//so:
destR = 0;
|
Теперь предположим, что вы хотите добавить еще немного зеленого, где раньше был красный. Поставьте «1» на входе 0x1, чтобы строка G гласила «1 1 0 0 0»:
Давайте теперь добьемся чего-то очень странного, изменив строку G на «0 -1 0 0 50»:
Что сейчас произошло? Например, если в каком-то случайном пикселе у вас был зеленый = 30, он был умножен на ‘-1’, а затем добавлено 50, поэтому результат будет: (30 * -1) + 50 = 20.
Поэтому создается тип порога : для каждого пикселя с зеленым значением, превышающим 50, его преобразованный пиксель будет полностью отключен. Почему? Хорошо, предположим, что зеленый канал пикселя имеет значение 51:
1
2
3
4
5
6
7
8
9
|
destG = ( 0 * srcR ) + ( -1 * srcG ) + ( 0 * srcB ) + ( 0 * srcA ) + 50;
//remember srcG = 51:
destG = 0 + (-51) + 0 + 0 + 50;
//so:
destG = — 51 + 50;
//so:
destG = -1;
//but a pixel can’t have a negative amount of green, so this is just set to zero:
destG = 0;
|
Теперь попробуйте это:
Все пиксели со значениями зеленого цвета больше 50 отключаются, а пиксели со значениями зеленого цвета ниже 50 увеличивают все три цветовых канала. Это позволяет вам видеть области изображения, которые имеют очень небольшое количество зеленого, как с изображением рыбы:
Здесь только пиксели с количеством зеленого меньше 50. Чем темнее пиксель, тем больше зеленого цвета в исходном изображении. Это основной принцип в любом случае. Я знаю, на первый взгляд это может показаться сложным, но поиграйте с этим, и в конце концов вы получите это 🙂
Оттенки серого
Хорошо, давайте перейдем к чему-то стандартному: изображение в градациях серого. Измените свою матрицу следующим образом:
У вас есть оттенки серого. Ницца 🙂
Перевернутые цвета
Давайте достигнем другого популярного цветового состояния: Inverted Colors.
Чтобы инвертировать цвета, мы должны сделать так, чтобы каждый пиксель со значением красного 255 имел значение красного ноля, и наоборот. То же самое для двух других цветов. Итак, нам нужно сделать так, чтобы Flash выполнялся так:
1
2
3
|
destR = 255 — srcR;
destG = 255 — srcG;
destB = 255 — srcB;
|
Но это легко! Все, что нам нужно сделать, это установить матрицу следующим образом:
Тада! Электрическая рыба:
Больше эффектов
Большинство из более экзотических эффектов, которые могут быть достигнуты с помощью ColorMatrixFilter, выполняются путем установки отрицательного значения для цвета и положительного значения для смещения — или наоборот. Положите «-1» от 0x3 до 2×3 (альфа) и 255 для смещения альфы (4×3).
Ух ты, теперь я знаю теперь, как они сделали Терминатор 2 🙂
Честно говоря, я не совсем уверен в том, что я только что сделал — через какое-то время становится очень сложно отслеживать вычисления.
Хотя можно понять, как ColorMatrixFilter работает с математической точки зрения, в действительности это будет вопрос игры с ним. Вы никогда не можете быть точно уверены, что произойдет, когда вы введете какие-то конкретные значения. Вот почему я сделал этот EffectsTester. Так что поиграй. Сделайте себя металлическим зеленым, или красным, или бесцветным.
Приложение реального мира
Когда у вас есть эффект, который вам нравится, вы можете применить его к любому DisplayObject (MovieClip, Sprite, Bitmap …) в вашем собственном коде, например так:
01
02
03
04
05
06
07
08
09
10
|
//first import ColorMatrixFilter up at the top of your code:
import flash.filters.ColorMatrixFilter;
//…later on:
var filters:Array = new Array();
//for everything after » = new», copy and paste from the «Grab The Code» box of EffectsTester:
var cmf:ColorMatrixFilter = new ColorMatrixFilter(new Array(-1,0,0,0,255,0,-1,0,0,255,0,0,-1,0,255,0,0,0,1,0));
//the next two lines apply the filter to your display object:
filters.push( cmf );
myDisplayObject.filters = filters;
|
Теперь давайте посмотрим на фильтр свертки.
Фильтр свертки
Из справочника по классу Adobe:
Свертка объединяет пиксели во входном изображении с соседними пикселями для получения изображения. С помощью свертки можно добиться большого разнообразия эффектов изображения, включая размытие, обнаружение краев, повышение резкости, тиснение и скашивание.
ConvolutionFilter проходит через все пиксели экранного объекта. Для каждого из них он использует значение центра в матрице в качестве значения текущего пикселя, которым манипулируют. Например, в матрице 3 x 3 центральное значение равно (1, 1). Затем он умножает значения из матрицы на окружающие пиксели и добавляет результирующие значения для всех пикселей, чтобы получить значение для результирующего центрального пикселя.
Понимание точной математики под матрицей Convolution стоит целой новой статьи, поэтому я не буду рассказывать обо всем этом здесь. Если вы хотите попасть в это, проверьте этот пост на adobe.com .
Однако простая игра со значениями в конечном итоге даст вам все возможные эффекты, которых вы можете достичь. И это будет весело 🙂 Итак, посмотрим, что мы можем сделать!
эксперимент
Фильтр свертки использует матрицу, как и фильтр цветовой матрицы. Опять же, значения варьируются от -255 до 255. И снова вы получаете большинство интересных эффектов, комбинируя отрицательные значения с положительными.
Позвольте мне поделиться с вами своими наблюдениями о том, как эта штука работает. Попробуйте увеличить случайное значение из матрицы. Что бы вы ни выбрали, это осветлит картину; если вы хотите, чтобы изображение оставалось на нормальной яркости, убедитесь, что значение «делителя» равно сумме всех значений в матрице.
Теперь, если вы попытаетесь опустить случайное значение ниже нуля, сохраняя хотя бы еще одно значение выше нуля, вы получите что-то там происходящее. Это влияет на ваши края:
Вот хороший: хотите выглядеть как солдат? 🙂 Попробуйте эти значения:
Теперь уменьшите значение «делителя» до «-1», чтобы стать солдатом на задании ночью.
Многое может быть достигнуто, если вы еще немного удерживаете кнопку мыши 🙂 Опустите и поднимите некоторые значения до крайности. Не забудьте отрегулировать «делитель» — это важно. Увеличьте свою матрицу. Сделайте это 5×5, например.
Приложение реального мира
Чтобы применить эффект в своем собственном коде, используйте объект filters , как вы это делали для ColorMatrixFilter:
01
02
03
04
05
06
07
08
09
10
|
//first import ConvolutionFilter up at the top of your code:
import flash.filters.ConvolutionFilter;
//…later on:
var filters:Array = new Array();
//for everything after » = new», copy and paste from the «Grab The Code» box of EffectsTester:
var cf:ConvolutionFilter = new ConvolutionFilter(3,3,new Array(1,0,-10,-2,3,1,6,1,-1),0);
//the next two lines apply the filter to your display object:
filters.push( cf );
myDisplayObject.filters = filters;
|
Наконец: попробуйте объединить оба фильтра.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
//first import the filter classes up at the top of your code:
import flash.filters.ColorMatrixFilter;
import flash.filters.ConvolutionFilter;
//…later on:
var filters:Array = new Array();
//for everything after » = new», copy and paste from the «Grab The Code» box of EffectsTester:
var cmf:ColorMatrixFilter = new ColorMatrixFilter(new Array(-1,0,0,0,255,0,-1,0,0,255,0,0,-1,0,255,0,0,0,1,0));
var cf:ConvolutionFilter = new ConvolutionFilter(3,3,new Array(1,0,-10,-2,3,1,6,1,-1),0);
//the next three lines apply the filters to your display object:
filters.push( cf );
filters.push( cmf );
myDisplayObject.filters = filters;
|
Получайте удовольствие, играя с этими фильтрами, и публикуйте любые полученные результаты в комментариях! Спасибо за прочтение.