O crossfade perfeito


25

Acho difícil descrever esse problema em palavras, e foi por isso que fiz um vídeo (45 segundos) para ilustrá-lo. Aqui está uma prévia das perguntas, dê uma olhada no Vimeo: http://vimeo.com/epologee/perfect-crossfade

Usando um crossfade linear, a imagem resultante terá um 'mergulho' na transparência.  Como posso evitar isso?

A questão de criar um crossfade ou dissolução impecável de duas imagens ou formas foi recorrente para mim em vários campos na última década. Primeiro na edição de vídeo, depois na animação em Flash e agora na programação para iOS. Quando você começa a pesquisar no Google, há muitas soluções alternativas a serem encontradas, mas eu realmente quero resolver isso sem hack neste momento.

O resumo:
qual é o nome da técnica ou curva a ser aplicada no crossfading de dois bitmaps da mesma cor e semitransparentes, se você desejar que a transparência resultante corresponda ao original de qualquer um?

Existe uma função (matemática) para calcular os valores alfa / transparência parciais necessários durante o desbotamento?

Existem linguagens de programação que têm estas funções como uma predefinição, semelhante ao ease in, ease outou ease in outfunções encontradas em ActionScript ou cacau?

Atualização: além do vídeo, fiz um projeto de amostra (requer Xcode e iOS SDK) e o publiquei no github. Ele mostra a mesma animação do vídeo, mas desta vez com quadrados: https://github.com/epologee/StackOverflow-Example-Code


7
Você não sabe nada a não ser marcar com +1 o vídeo.
sebastiangeiger

Depende de como o operador over é implementado. Veja en.wikipedia.org/wiki/Alpha_channel
artistoex

Concordo, @artistoex, há algo nesse operador, obrigado pelo link! No entanto, se a resposta estiver enterrada em algum lugar, não a estou vendo :(
epologee

A representação matemática do operador over leva a uma equação. Exemplo sobre operador: C = alfa * c1 + (alfa-1) * c2 produz alfa = (C + c2) / (c1 + c2) (C sendo o resultado da mistura das duas cores c1, c2). Isso significa que, para esse operador excedente, não há função que satisfaça sua condição.
Artistoex

Para C = alfa1 * c1 + alfa2 * c2 (0 <= alfa1, alfa2 <= 1), existe a seguinte função: alfa1 = (C-alfa2 * c2) / c1.
Artistoex

Respostas:



3

Não sei qual pode ser o nome no campo da edição de vídeo, mas eu chamaria a curva de curva S ou curva sigmóide . Deve ser muito simples produzir o cross-fade que você está procurando no iOS usando a função de tempo kCAMediaTimingFunctionEaseInEaseOut da Core Animation . Apenas anime a alphapropriedade de duas visualizações em direções opostas (uma 0-> 1, uma 1-> 0) usando essa função de tempo:

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

Nota: Você realmente deve usar os métodos de animação baseados em blocos em vez dos métodos de conveniência do UIView. Eu usei os métodos do UIView acima porque é muito fácil de entender e fácil de digitar a partir da memória. Usar blocos não é muito mais difícil, no entanto.

Adendo: Se você não gostar do UIViewAnimationEaseInOut, poderá criar sua própria função de tempo, conforme descrito em Tempo, Espaços de tempo e CAAnimation . Isso é um pouco mais avançado do que a animação simples ilustrada acima, mas oferece todo o controle que você deseja.


Sigmoid! Isso já está um passo mais perto, obrigado! O trecho de código que você fornece não funciona imediatamente, pois o setAnimationCurve usa um parâmetro diferente de kCAMediaTimingFunctionEaseInEaseOut. Você poderia ter significado UIViewAnimationCurveEaseInOut? O problema com essa curva é o mesmo (mergulho no meio), porque a qualquer momento os dois valores alfa em uma adição simples serão iguais 1.0, onde, como na minha curva ajustada manualmente, é necessário exceder 1.0para obter os resultados desejados .
epologee

Entendo agora ... você está certo sobre a constante - atualizei o código na resposta. Também adicionei um link para documentos que explicam como criar suas próprias funções de tempo.
Caleb

Eu faço minhas animações com blocos, mas a essência é a mesma. As curvas incorporadas ainda não se aplicam, devido à sua simetria, mas o adendo abriu o caminho para uma CAMediaTimingFunction personalizada que combinava com a que eu usei no vídeo do After Effects. O mais preocupante é que não existe uma curva sigmóide que se adapta a todos os cenários ; diferentes níveis iniciais de opacidade exigirão diferentes posições de bezier para se livrar do 'mergulho'. Deve estar faltando algo.
epologee

Oi @ Caleb, publiquei um projeto de amostra no GitHub (consulte a publicação). O tempo personalizado é útil, mas se você alterar o initialTransparencyvalor, não adianta. Você não teria idéia do que tentar em seguida?
epologee

2
Mais alguns pedacinhos para ajudar as pesquisas do Google; programadores gráficos chamam o gráfico que você está falando de "passo suave". Programadores altamente matemáticos costumam chamá-lo de "interpolador de hermitas". E uma equação simples para calcular uma sem trigonometria é: "3t ^ 2 - 2t ^ 3".
Trevor Powell

1

Na computação gráfica, esse tipo de função é chamada de passo suave . Quando usado para crossfade, determina o valor global do alfa para a composição.

Se as imagens de entrada tiverem um canal alfa, primeiro verifique se o alfa é pré - multiplicado . Em seguida, você pode fazer a composição do crossfade diretamente, usando o passo suave alphaem cada canal [ X = A*alpha + B*(1-alpha)] e esperar resultados razoáveis.


0

Você pode usar a função de decaimento exponencial:

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

Seu gráfico se parece mais com:

Alpha1(time) = sin(time * 0.5 * pi / transitionTime); // fade in
Alpha2(time) = cos(time * 0.5 * pi / transitionTime); // fade out

Obrigado @Danny. Na verdade, a execução da 1 - Alpha1(time)equação não resolverá o problema, porque duas imagens combinadas de 0,5 alfa não resultarão em uma imagem composta com 1,0 alfa. As curvas personalizadas que desenhei não são espelhadas verticalmente.
epologee

1
O 1-alfa era para o decaimento exponencial, que eu acho mais adequado. Para a sen / cos funções de curso sin (t) = sqrt (1-SQR (cos (t)), no entanto, o cálculo de cada um separadamente deve ser mais rápido.
Danny Varod

Se o problema era como seria a função de uma curva semelhante, sua matemática está correta. No entanto, a questão é como lidar com a mistura de duas cores, por exemplo, como obter 40% azul + 40% azul para resultar em 80% azul.
epologee

Isso é fácil de fazer, mas resultaria em uma saturação com aparência ruim quando a soma das cores fosse> 100%.
Danny Varod
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.