Ідеальний перехресний шар


25

Мені важко описати цю проблему словами, через що я зробив відео (45 секунд), щоб проілюструвати її. Ось попередній перегляд питань, ознайомтеся з ними на Vimeo: http://vimeo.com/epologee/perfect-crossfade

Використовуючи лінійну перехрещу, отримане зображення матиме прозорість.  Як я можу запобігти цьому?

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

Короткий підсумок:
Як називається техніка або крива, яку слід застосувати для кросфіддінгу двох напівпрозорих одноколірних растрових зображень, якщо ви хочете, щоб отримана прозорість відповідала оригіналу будь-якого з них?

Чи існує (математична) функція для обчислення необхідних часткових значень прозорості / альфа під час згасання?

Чи існують мови програмування, які мають ці функції як попередньо встановлені, подібні до функцій ease in, ease outабо ease in outфункції, що містяться в ActionScript або Cocoa?

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


7
Не знаю нічого про це, окрім +1 для відео.
sebastiangeiger

Залежить від того, як реалізований оператор over. Дивіться en.wikipedia.org/wiki/Alpha_channel
artistoex

Я згоден, @artistoex, щось над цим у оператора, дякую за посилання! Однак якщо відповідь похований десь там, я не бачу цього :(
epologee

Математичне подання над оператором призводить до рівняння. Приклад щодо оператора: C = альфа * c1 + (альфа-1) * c2 дає альфа = (C + c2) / (c1 + c2) (C є результатом змішування двох кольорів c1, c2). Це означає, що для цього оператора немає функції, яка б відповідала вашій умові.
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, якщо ви не хочете, щоб область накладки була проглянута наскрізь.


3

Я не знаю, яке ім'я може бути у царині редагування відео, але я б назвав криву S-кривою або сигмоподібною кривою . Створити перехресне випромінювання, яке ви шукаєте в iOS, слід дуже просто, використовуючи функцію timing 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)], і очікувати розумних результатів.


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

Дякую @Danny Насправді виконання 1 - Alpha1(time)рівняння не допоможе зануритись, оскільки два змішаних 0,5 альфа-зображення не призведуть до складеного зображення з 1,0 альфа. Спеціальні криві, які я намалював, не відображаються вертикально.
epologee

1
1-альфа був для експоненціального розпаду, який, на мою думку, є більш підходящим. Для функцій sin / cos, звичайно, sin (t) = sqrt (1-sqr (cos (t)), однак, обчислення кожного окремо повинно бути швидшим.
Денні Варод

Якщо питання полягало в тому, як може виглядати функція подібної кривої, ваша математика правильна. Однак питання полягає в тому, як боротися зі змішуванням двох кольорів, наприклад, як отримати 40% синього + 40% синього, щоб отримати 80% синього.
epologee

Це легко зробити, але це призведе до поганої насиченості, коли сума кольорів> 100%.
Danny Varod
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.