Sweeeet
10. October 2005, 09:30
Hallo! Ich hoffe, was ich teilen möchte, verdient das Attribut "fortgeschritten".
Folgende Problemstellung: Ich hab meine Digicam aufs Fenstersims gestellt und alle 30 Sekunden ein Bild vom Himmel gemacht, insgesamt ein paarhundert. Daraus habe ich einen Zeitrafferfilm zusammengebastelt. Dann wollte ich die Zeit eingeblendet haben. Als Text war's natürlich überhaupt kein Problem dank ScriptClip(), aber ich wollte es als analoge Uhr haben. Es hat mich einige Zeit gekostet, aber nun hab ich eine Lösung mit der ich sehr zufrieden bin.
Im Anhang ist ein Bildchen davon und ich hab mal eine kleine Demo (Megaupload, 658 kB) (http://www.megaupload.com/?d=1LMKR4UP) upgeloadet.
Hier die Vorgehensweise in Kürze:
Mit PHP (standalone) einen Satz Bilder (PNG) des Ziffernblatts mit Stundenzeiger in 60 verschiedenen Positionen erzeugt.
Ebenso einen Satz PNGs nur mit dem Minutenzeiger in 60 verschiedenen Positionen erzeugt.
Ein AviSynth-Script erstellt, das aus der Framenummer die jeweiligen Frames aus dem "Stunden"- und "Minuten"-Film herauspickt und übereinanderlegt.
Zusätzlich noch eine Funktion, um aus den Framenummern das amerikanische Zeitformat (AM/PM) erzeugt und mit Subtitle() darstellt.
Wer sich für das PHP-Script interessiert bitte melden (ist ausführlich kommentiert). Das AviSynth-Script pack ich hier mal rein, obwohl es leider noch wie Kraut und Rüben aussieht :ani_lol:. Fragen, Anregungen und vor allem Verbesserungsvorschläge nehme ich gerne entgegen. Eine kleine Frage habe ich selber auch: Gibt's einen verbreiteten Codec, mit dem man Filme mit sehr wenigen Farben (in diesem Fall 3) und Bewegung (nur der Zeiger) verlustfrei stark komprimieren kann? Früher gab's FLI für sowas, heute animated GIFs, aber die kann man schlecht weiterverarbeiten.
antialias = TRUE
global time_factor = 30
global time_offset = 39049
global clock_x = 160
# Load original clip.
cl1 = AviSource("Irgendeinpfad/himmel.avi").ConvertToRGB32
cl1 = cl1.trim(300, 0)
# Resize to double size if antialiasing on.
global cl2 = antialias ? cl1.BilinearResize(cl1.Width * 2, cl1.Height * 2) : cl1
cl_hour = ImageReader("Irgendeinpfad/clock_h_%02d.png", 0, 59).ConvertToRGB32
global cl_hour = ResetMask(cl_hour).ColorKeyMask($00ff00, 0)
cl_minute = ImageReader("Irgendeinpfad/clock_m_%02d.png", 0, 59).ConvertToRGB32
global cl_minute = ResetMask(cl_minute).ColorKeyMask($00ff00, 0)
cl5 = ScriptClip(cl2, "OverlayClock(cl2, current_frame)")
cl_out = antialias ? cl5.BilinearResize(cl5.Width / 2, cl5.Height / 2) : cl5
cl_out
AssumeFps(24)
Function OverlayClock(clip, frame) {
time = frame * time_factor + time_offset
minute_index = Round(time / 60) % 60
hour_index = Round(time / 720) % 60
cl7 = cl_hour.trim(hour_index, -1)
cl8 = cl_minute.trim(minute_index, -1)
cl5 = Layer(clip, cl7, "add", 255, clock_x)
cl6 = Layer(cl5, cl8, "add", 255, clock_x)
cl6 = cl6.Subtitle(sec2time(time), font="Arial", size=100, align=2, text_color=$ffffff)
return(cl6)
}
Function sec2time(s) {
minutes = s / 60
seconds = s % 60
hours = minutes / 60
minutes = minutes % 60
days = hours / 24
ampm = (hours % 24 > 11) ? "PM" : "AM"
hours = (hours - 1) % 12 + 1
minutes = minutes % 60
out = (days > 0) ? String(days) + " d " : ""
out = out + String(hours, "% 2.0f")
out = out + ":" + String(minutes, "%02.0f")
out = out + " " + ampm
return(out)
}
Folgende Problemstellung: Ich hab meine Digicam aufs Fenstersims gestellt und alle 30 Sekunden ein Bild vom Himmel gemacht, insgesamt ein paarhundert. Daraus habe ich einen Zeitrafferfilm zusammengebastelt. Dann wollte ich die Zeit eingeblendet haben. Als Text war's natürlich überhaupt kein Problem dank ScriptClip(), aber ich wollte es als analoge Uhr haben. Es hat mich einige Zeit gekostet, aber nun hab ich eine Lösung mit der ich sehr zufrieden bin.
Im Anhang ist ein Bildchen davon und ich hab mal eine kleine Demo (Megaupload, 658 kB) (http://www.megaupload.com/?d=1LMKR4UP) upgeloadet.
Hier die Vorgehensweise in Kürze:
Mit PHP (standalone) einen Satz Bilder (PNG) des Ziffernblatts mit Stundenzeiger in 60 verschiedenen Positionen erzeugt.
Ebenso einen Satz PNGs nur mit dem Minutenzeiger in 60 verschiedenen Positionen erzeugt.
Ein AviSynth-Script erstellt, das aus der Framenummer die jeweiligen Frames aus dem "Stunden"- und "Minuten"-Film herauspickt und übereinanderlegt.
Zusätzlich noch eine Funktion, um aus den Framenummern das amerikanische Zeitformat (AM/PM) erzeugt und mit Subtitle() darstellt.
Wer sich für das PHP-Script interessiert bitte melden (ist ausführlich kommentiert). Das AviSynth-Script pack ich hier mal rein, obwohl es leider noch wie Kraut und Rüben aussieht :ani_lol:. Fragen, Anregungen und vor allem Verbesserungsvorschläge nehme ich gerne entgegen. Eine kleine Frage habe ich selber auch: Gibt's einen verbreiteten Codec, mit dem man Filme mit sehr wenigen Farben (in diesem Fall 3) und Bewegung (nur der Zeiger) verlustfrei stark komprimieren kann? Früher gab's FLI für sowas, heute animated GIFs, aber die kann man schlecht weiterverarbeiten.
antialias = TRUE
global time_factor = 30
global time_offset = 39049
global clock_x = 160
# Load original clip.
cl1 = AviSource("Irgendeinpfad/himmel.avi").ConvertToRGB32
cl1 = cl1.trim(300, 0)
# Resize to double size if antialiasing on.
global cl2 = antialias ? cl1.BilinearResize(cl1.Width * 2, cl1.Height * 2) : cl1
cl_hour = ImageReader("Irgendeinpfad/clock_h_%02d.png", 0, 59).ConvertToRGB32
global cl_hour = ResetMask(cl_hour).ColorKeyMask($00ff00, 0)
cl_minute = ImageReader("Irgendeinpfad/clock_m_%02d.png", 0, 59).ConvertToRGB32
global cl_minute = ResetMask(cl_minute).ColorKeyMask($00ff00, 0)
cl5 = ScriptClip(cl2, "OverlayClock(cl2, current_frame)")
cl_out = antialias ? cl5.BilinearResize(cl5.Width / 2, cl5.Height / 2) : cl5
cl_out
AssumeFps(24)
Function OverlayClock(clip, frame) {
time = frame * time_factor + time_offset
minute_index = Round(time / 60) % 60
hour_index = Round(time / 720) % 60
cl7 = cl_hour.trim(hour_index, -1)
cl8 = cl_minute.trim(minute_index, -1)
cl5 = Layer(clip, cl7, "add", 255, clock_x)
cl6 = Layer(cl5, cl8, "add", 255, clock_x)
cl6 = cl6.Subtitle(sec2time(time), font="Arial", size=100, align=2, text_color=$ffffff)
return(cl6)
}
Function sec2time(s) {
minutes = s / 60
seconds = s % 60
hours = minutes / 60
minutes = minutes % 60
days = hours / 24
ampm = (hours % 24 > 11) ? "PM" : "AM"
hours = (hours - 1) % 12 + 1
minutes = minutes % 60
out = (days > 0) ? String(days) + " d " : ""
out = out + String(hours, "% 2.0f")
out = out + ":" + String(minutes, "%02.0f")
out = out + " " + ampm
return(out)
}