Идеальный переход

25

Мне трудно описать эту проблему словами, поэтому я сделал видео (45 секунд), чтобы проиллюстрировать это. Вот предварительный просмотр вопросов, пожалуйста, посмотрите на Vimeo: http://vimeo.com/epologee/perfect-crossfade

Используя линейное перекрестное затухание, полученное изображение будет иметь «прозрачность».  Как я могу предотвратить это?

Проблема создания безупречного перекрестного затухания или растворения двух изображений или форм постоянно возникала у меня в ряде областей в течение последнего десятилетия. Сначала в редактировании видео, затем во флэш-анимации, а теперь в программировании на iOS. Когда вы начинаете гуглить, есть много обходных путей, но я действительно хочу решить это без взлома на этот раз.

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

Существует ли (математическая) функция для расчета необходимых значений частичной прозрачности / альфа во время затухания?

Существуют языки программирования , которые имеют эти функции в качестве предварительной настройки, сходные с ease in, ease outили ease in outфункции , найденные в ActionScript или какао?

Обновление: в дополнение к видео, я сделал пример проекта (требуется Xcode и iOS SDK) и разместил его на github. Он показывает ту же анимацию, что и видео, но на этот раз с квадратами: https://github.com/epologee/StackOverflow-Example-Code

epologee
источник
7
Ничего не знаю об этом, но +1 за видео.
Себастьян
Зависит от того, как реализован оператор over. См en.wikipedia.org/wiki/Alpha_channel
artistoex
Я согласен, @artistoex, в этом есть что-то сверх оператора, спасибо за ссылку! Однако, если ответ где-то похоронен, я его не вижу :(
epologee 13.11.11
Математическое представление оператора over приводит к уравнению. Пример над оператором: C = alpha * c1 + (alpha-1) * c2 дает alpha = (C + c2) / (c1 + c2) (C является результатом смешивания двух цветов c1, c2). Это означает, что для этого оператора over, нет функции, которая удовлетворяет вашему условию.
artistoex
Для C = alpha1 * c1 + alpha2 * c2 (0 <= alpha1, alpha2 <= 1) есть такая функция: alpha1 = (C-alpha2 * c2) / c1.
artistoex

Ответы:

3

Боюсь, это невозможно. Вот как прозрачность рассчитывается при наложении двух объектов: http://en.wikipedia.org/wiki/Alpha_compositing

Альфа-композитинг

Один из объектов должен иметь непрозрачность 1, если вы не хотите, чтобы область наложения была видимой.

b123400
источник
3

Я не знаю, какое название может быть в области редактирования видео, но я бы назвал эту кривую S-образной или сигмовидной кривой . Должно быть очень просто создать перекрестное затухание, которое вы ищете в iOS, используя функцию синхронизации kCAMediaTimingFunctionEaseInEaseOut в Core Animation . Просто анимируйте alphaсвойство двух видов в противоположных направлениях (один 0-> 1, один 1-> 0), используя эту функцию синхронизации:

[UIView beginAnimations:@"crossfade" context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
view1.alpha = 0.0;
view2.alpha = 1.0;
[UIView commitAnimations];

Примечание. Вы должны действительно использовать методы анимации на основе блоков вместо удобных методов UIView. Я использовал методы UIView выше, потому что это очень легко понять и легко набирать из памяти. Однако использование блоков не намного сложнее.

Приложение: Если вам не нравится UIViewAnimationEaseInOut, вы можете создать свою собственную функцию синхронизации, как описано в разделах Синхронизация , Пространства времени и CAAnimation . Это немного сложнее, чем простая анимация, показанная выше, но она дает вам все необходимое управление.

Калеб
источник
Сигмовидной! Это уже на шаг ближе, спасибо! Предоставляемый вами фрагмент кода не работает сразу, так как setAnimationCurve принимает параметр, отличный от kCAMediaTimingFunctionEaseInEaseOut. Могли ли вы иметь в виду UIViewAnimationCurveEaseInOut? Однако проблема с этой кривой такая же (провал в середине), потому что в любой момент времени два альфа-значения в простом сложении будут равны 1.0, где, как и в моей кривой, отрегулированной вручную, она должна превышать, 1.0чтобы получить желаемые результаты. ,
epologee
Теперь я вижу ... вы правы насчет константы - я обновил код в ответе. Я также добавил ссылку на документы, которые объясняют, как создавать свои собственные функции синхронизации.
Калеб
Я делаю анимацию с блоками, но суть та же. Встроенные кривые по-прежнему не применяются из-за их симметрии, но приложение проложило путь к пользовательской функции CAMediaTimingFunction, которая соответствовала той, которую я использовал в видео After Effects. Беспокойство заключается в том, что не существует ни одной сигмоидальной кривой, подходящей для каждого сценария , разные начальные уровни непрозрачности потребуют разных положений Безье, чтобы избавиться от «провала». Там должно быть что-то, что я скучаю.
epologee
Привет @Caleb, я разместил пример проекта на GitHub (см. Пост). Настраиваемое время полезно, но если вы измените initialTransparencyзначение, оно бесполезно. Вы бы не поняли, что попробовать дальше?
epologee
2
Еще несколько маленьких кусочков, чтобы помочь поиску Google; Графические программисты называют график, о котором вы говорите, «плавным шагом». Очень математические программисты будут часто называть это «интерполятором Эрмита». И простое уравнение для вычисления без тригонометрии: «3t ^ 2 - 2t ^ 3».
Тревор Пауэлл
1

В компьютерной графике этот вид функции называется плавным шагом . При использовании для кроссфейда он определяет глобальное альфа-значение для композиции.

Если у входных изображений есть альфа-канал, вы должны сначала убедиться, что альфа- канал предварительно умножен . Затем вы можете выполнить композицию кроссфейдера напрямую, используя сглаживание alphaдля каждого канала [ X = A*alpha + B*(1-alpha)], и ожидать приемлемых результатов.

comingstorm
источник
0

Вы можете использовать функцию экспоненциального затухания:

Alpha1(time) = 1 - exp(-time / (0.2 * transitionTime)); // fade in
Alpha2(time) = 1 - Alpha1(time); // fade out

Ваш график больше похож на:

Alpha1(time) = sin(time * 0.5 * pi / transitionTime); // fade in
Alpha2(time) = cos(time * 0.5 * pi / transitionTime); // fade out
Дэнни Варод
источник
Спасибо @ Дэнни. На самом деле, выполнение 1 - Alpha1(time)уравнения не позаботится о провале, потому что два смешанных 0,5 альфа-изображения не приведут к составному изображению с 1,0 альфа. Пользовательские кривые, которые я нарисовал, не отражаются вертикально.
epologee
1
1-альфа была для экспоненциального затухания, которое, я думаю, больше подходит. Однако для функций sin / cos, конечно, sin (t) = sqrt (1-sqr (cos (t))), вычисление каждой из них должно выполняться быстрее
Дэнни Варод,
Если бы проблема заключалась в том, как могла бы выглядеть функция аналогичной кривой, ваша математика верна. Однако вопрос заключается в том, как бороться со смешиванием двух цветов, например, как получить 40% синего + 40% синего, чтобы получить 80% синего.
epologee
Это легко сделать, но это приведет к плохо выглядящей насыщенности, когда сумма цветов> 100%.
Дэнни Варод