Persimpangan sempurna


25

Saya kesulitan menggambarkan masalah ini dengan kata-kata, itulah sebabnya saya membuat video (45 detik) untuk menggambarkannya. Ini adalah preview dari pertanyaan-pertanyaan tersebut, silakan lihat di Vimeo: http://vimeo.com/epologee/perfect-crossfade

Menggunakan linear crossfade, gambar yang dihasilkan akan memiliki 'penurunan' dalam transparansi.  Bagaimana saya bisa mencegah ini?

Masalah membuat crossfade sempurna atau melarutkan dua gambar atau bentuk telah berulang kepada saya di sejumlah bidang selama dekade terakhir. Pertama dalam pengeditan video, kemudian dalam animasi Flash dan sekarang dalam pemrograman iOS. Ketika Anda mulai mencari di Google, ada banyak solusi yang dapat ditemukan, tetapi saya benar-benar ingin menyelesaikan ini tanpa peretasan saat ini.

Ringkasan:
Apa nama teknik atau kurva untuk diterapkan dalam crossfading dua bitmap semi-transparan, berwarna sama, jika Anda ingin transparansi yang dihasilkan sesuai dengan yang asli dari salah satu dari itu?

Apakah ada fungsi (matematis) untuk menghitung nilai transparansi / alpha parsial yang diperlukan selama fade?

Apakah ada bahasa pemrograman yang memiliki fungsi-fungsi ini sebagai preset, mirip dengan ease in, ease outatau ease in outfungsi yang ditemukan di ActionScript atau Cocoa?

Pembaruan: Selain video, saya telah membuat proyek sampel (memerlukan Xcode dan iOS SDK) dan mempostingnya di github. Ini menunjukkan animasi yang sama dengan video tetapi kali ini dengan kotak: https://github.com/epologee/StackOverflow-Example-Code


7
Tidak tahu apa-apa selain +1 untuk video.
sebastiangeiger

Tergantung pada bagaimana operator berlebih diimplementasikan. Lihat en.wikipedia.org/wiki/Alpha_channel
artistoex

Saya setuju, @artistoex, ada sesuatu pada operator itu, terima kasih untuk tautannya! Namun, jika jawabannya terkubur di sana di suatu tempat, saya tidak melihatnya :(
epologee

Representasi matematis dari operator over mengarah ke persamaan. Contoh over operator: C = alpha * c1 + (alpha-1) * c2 menghasilkan alpha = (C + c2) / (c1 + c2) (C menjadi hasil dari pencampuran dua warna c1, c2). Ini berarti untuk operator over ini, tidak ada fungsi, yang memenuhi kondisi Anda.
artistoex

Untuk C = alpha1 * c1 + alpha2 * c2 (0 <= alpha1, alpha2 <= 1), ada fungsi seperti itu: alpha1 = (C-alpha2 * c2) / c1.
artistoex

Jawaban:



3

Saya tidak tahu nama apa yang mungkin ada dalam dunia pengeditan video, tapi saya akan menyebut kurva itu kurva S-kurva atau kurva sigmoid . Seharusnya sangat sederhana untuk menghasilkan cross-fade yang Anda cari di iOS menggunakan Core Animation's kCAMediaTimingFunctionEaseInEaseOut fungsi waktu. Hanya menghidupkan alphaproperti dari dua tampilan dalam arah yang berlawanan (satu 0-> 1, satu 1-> 0) menggunakan fungsi pengaturan waktu:

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

Catatan: Anda harus benar-benar menggunakan metode animasi berbasis blok alih-alih metode kenyamanan UIView. Saya menggunakan metode UIView di atas karena sangat mudah dimengerti, dan mudah diketik dari memori. Namun, menggunakan blok tidak jauh lebih sulit.

Tambahan: Jika Anda tidak menyukai UIViewAnimationEaseInOut, Anda dapat membuat fungsi pengaturan waktu Anda sendiri seperti yang dijelaskan dalam Pengaturan Waktu, Ruang Waktu, dan CAAnimation . Itu sedikit lebih maju daripada animasi sederhana yang digambarkan di atas, tetapi memberi Anda semua kontrol yang Anda inginkan.


Sigmoid! Itu sudah selangkah lebih dekat, terima kasih! Sepotong kode yang Anda berikan tidak langsung berfungsi, karena setAnimationCurve mengambil parameter yang berbeda dari kCAMediaTimingFunctionEaseInEaseOut. Bisakah Anda berarti UIViewAnimationCurveEaseInOut? Masalah dengan kurva itu adalah sama (turun di tengah), karena pada suatu titik waktu, dua nilai alpha dalam penambahan sederhana akan sama 1.0, di mana seperti pada kurva tweak manual saya perlu melebihi 1.0untuk mendapatkan hasil yang diinginkan .
Epologee

Saya mengerti sekarang ... Anda benar tentang konstanta - Saya telah memperbarui kode dalam jawabannya. Saya juga menambahkan tautan ke dokumen yang menjelaskan cara membuat fungsi pengaturan waktu Anda sendiri.
Caleb

Saya melakukan animasi saya dengan balok, namun intinya sama. Kurva bawaan masih tidak berlaku, karena simetri mereka, tetapi addendum membuka jalan ke fungsi CAMediaTimingFac kustom yang cocok dengan yang saya gunakan dalam video After Effects. Masalahnya adalah bahwa tidak ada satu kurva sigmoid yang sesuai dengan setiap skenario , tingkat awal opacity yang berbeda akan membutuhkan posisi bezier yang berbeda untuk menghilangkan 'dip'. Pasti ada sesuatu yang saya lewatkan.
Epologee

Hai @ Caleb, saya memposting proyek sampel di GitHub (lihat posting). Pengaturan waktu kustom sangat membantu, tetapi jika Anda mengubah initialTransparencynilainya, tidak ada gunanya. Anda tidak akan memiliki petunjuk apa yang harus dicoba selanjutnya?
Epologee

2
Beberapa bit lagi untuk membantu pencarian Google; pemrogram grafik menyebut grafik yang Anda bicarakan "smoothstep". Pemrogram yang sangat matematika sering menyebutnya "interpolator hermite". Dan persamaan sederhana untuk menghitung satu tanpa trigonometri adalah: "3t ^ 2 - 2t ^ 3".
Trevor Powell

1

Dalam grafik komputer, fungsi semacam ini disebut smoothstep . Ketika digunakan untuk crossfade, itu menentukan nilai alpha global untuk komposisi.

Jika gambar input memiliki saluran alfa, Anda harus terlebih dahulu memastikan bahwa alfa adalah pra - ditanamkan . Kemudian, Anda dapat melakukan komposisi crossfade secara langsung, menggunakan smoothstep alphapada setiap saluran [ X = A*alpha + B*(1-alpha)], dan mengharapkan hasil yang masuk akal.


0

Anda dapat menggunakan fungsi peluruhan eksponensial:

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

Grafik Anda lebih mirip:

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

Terima kasih @Danny. Sebenarnya, melakukan 1 - Alpha1(time)persamaan tidak akan menangani penurunan, karena dua gambar 0,5 alpha campuran tidak akan menghasilkan gambar yang dikomposisi dengan 1,0 alpha. Kurva khusus yang saya gambar tidak dicerminkan secara vertikal.
Epologee

1
1-alpha adalah untuk peluruhan eksponensial, yang menurut saya lebih cocok. Untuk fungsi sin / cos tentu saja dosa (t) = sqrt (1-sqr (cos (t)), bagaimanapun, menghitung masing-masing secara terpisah harus lebih cepat
Danny Varod

Jika masalahnya adalah seperti apa fungsi kurva serupa, matematika Anda benar. Namun masalahnya adalah bagaimana menangani pencampuran dua warna, misalnya bagaimana mendapatkan 40% biru + 40% biru untuk menghasilkan 80% biru.
Epologee

Itu mudah dilakukan tetapi akan menghasilkan saturasi tampak buruk ketika jumlah warna> 100%.
Danny Varod
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.