Mammamia, da wollte ich mich mal etwas intensiver mit AVISynth befassen und auch ein wenig Programmierung lernen, aber ich scheitere bereits an simplen Schleifen. Spinn' ich, oder sind Schleifen wirklich nur durch Rekursion möglich?
Die Aufgabe, die ich mir selber stellte war, einen schwarzen Clip mit immer heller werdenden Streifen zu verbreitern - es sollte ja einfach bleiben ... ha! . Dazu sollte ein Counter pro Durchlauf um 16 erhöht werden, solange er kleiner als 236 ist. Bei jedem Durchlauf sollte außerdem ein schwarzer Clip um den Wert vom Counter mit Tweak aufgehellt und mit StackHorizontal an den bisherigen Clip angehängt werden. Aber alles was ich hinbekommen habe, waren üble Abstürze und Syntax-Fehler.
Kann mir mal jemand da ein wenig auf die Sprünge helfen?
AVISynth und programmierung
-
-
kannst Du mal Bilder malen, wie das aussehen soll?
-
@katja
Das bringt eigentlich nicht viel, weil hier der Weg das Ziel war.
Aus 16 Balken von je 44 Pixel Breite sollte ein Bild zusammengesetzt werden, das von links nach rechts aufsteigend in 16ner-Schritten die Luma-Werte von 16-236 enhalten sollte.
In C etwa so:
clip1=BlankClip(length=300, width=44, height=256, fps=25, pixel_type="yuy2", color=$000000);
clip2=clip1;
counter=16;
if (counter<=236) {
StackHorizontal(clip1,Tweak(clip2,bright=counter));
counter+=16;
}
Return(clip1) -
aber es geht nicht so, weil der Film ja immer größer wird.Oder wie oder was?
Male das mittle und das Final Bild Trotzdem.
ich kann mir das sonst nicht vorstellen.hab schon ne Idee mit ScriptClip oder Animate.
EDIT1:
erstmal Stufenlos ohne *16Codeclip1=BlankClip(length=300,width=44,height=256,fps=25,pixel_type="yuy2",color=$000000)Clip2=Animate(clip1,0,236,"Tweak",0,0,16,0,0,236)StackHorizontal(clip1,clip2)
EDIT2:
jetzt mit 16Codeclip1=BlankClip(length=300,width=44,height=256,fps=25,pixel_type="yuy2",color=$000000) Clip2=Animate(clip1,0,236,"Tweak",0,0,16,0,0,236).SelectEvery(16,0) StackHorizontal(clip1,clip2)
Und Du willst jetzt
Balken1 = Tweak0
Balken2 = Tweak16
Balken3 = Tweak32
usw?ui Robby Zeit........
-
@katja
Zitat
Und Du willst jetzt
Balken1 = Tweak0
Balken2 = Tweak16
Balken3 = Tweak32
usw?
Genau das war das Ziel, ja. Wobei als Endergebnis ein Bild von 704x288 mit exakt 16 Balken entstehen sollte.
Dabei stand aber mehr das Erlernen der Syntax an sich im Vordergrund, weniger das Ergebnis (das aber trotzdem richtig sein sollte ).
Ich habe vor vieeeelen Jahren mal in reinem C und Z80- sowie 86K-Assembler programmieren gelernt. Aber OOP und AVISynth allgemein stellen mich vor Rätsel - viele Rätsel.
Ich krieg' echt die Kriese, wenn ich sehe, wie Leute wie Didée oder scharfi auch komplexe Scripts anscheinend einfach so aus dem Ärmel schütteln - das will ich auch können *grummel*
Aber bevor ich mich an komplexe Problemstellungen heranwage, möchte ich erstmal AVISynth verstehen lernen - und das wehrt sich! *unerhört!* -
Ich weiß nicht, ob dir hier der Quelltext von "Array4x4" noch weiterhilft, denn es scheint, als ob dein Problem doch etwas abweicht...
-
Hm, mal davon abgesehen, dass das Sript bei mir nicht funktioniert, sehe ich da nichts, was sich als echte Schleife bezeichnen ließe.
WAS ich sehe, sind jede MEnge syntaktischer Feinheiten, die mich in den Wahnsinn treiben. Irgendwie kann ich mich mit der Fallentscheidung ? 1 : 2 nicht so recht anfreunden... *seufz* Mir stecken wohl die "alten" Programmiermethoden zu sehr in den Knochen. "Wenn das da wahr ist, dann mach das da, basta" ist eher die Art, wie ich früher mal programmieren konnte. -
Naja, 'neu' ist der Fragezeichenoperator nun wirklich nicht, mag den aber auch nicht.
Cu Selur
-
Zitat von Kika
Aber bevor ich mich an komplexe Problemstellungen heranwage, möchte ich erstmal AVISynth verstehen lernen - und das wehrt sich! *unerhört!*
/----/
Irgendwie kann ich mich mit der Fallentscheidung ? 1 : 2 nicht so recht anfreunden...
Sieh's doch mal als "Übersetzung":IF condition THEN do_this ELSE do_that
Streiche "IF", ersetze "THEN" --> "?", und "ELSE" --> ":"
condition ? do_this : do_that
Ebenfalls als Programmierer alter Schule (seit ca. 13 Jahren keinen Compiler mehr angefasst) sag ich mal: AviSynth Scripting ist einfach, wirklich einfach. Alles nur eine Sache der Semantik - man muss sich halt daran gewöhnen.
-
Zitat
man muss sich halt daran gewöhnen.
Tja, an die einfachen Dinge habe ich mich inzwischen auch gewöhnt, komplexere Strukturen bereiten mir aber nach wie vor Schwierigkeiten. Und ich bin so an das Programmieren mit Schleifen - welcher Art auch immer - gewöhnt, dass ich ohne fast "nackt" dastehe.
Ich hatte versucht, das Balken-Problem mit einer Funktion zu lösen, die sich selbst aufruft, das hat aber jedesmal geknallt. Sowas zum Beispiel:
Zitat
global clip1=BlankClip(length=300, width=44, height=256, fps=25, pixel_type="yuy2", color=$000000)
global clip2=clip1
global counter=16
countit()
return(clip1)
function CountIt() {
(counter <=236) ? count2() : return()
}
function Count2() {
StackHorizontal(clip1,Tweak(clip2,bright=counter))
counter=counter+16
countIt()
}
Sowas wie das hier funktioniert allerdings:Zitatmode="RGB24"
black = blankclip(width=400,height=1,pixel_type=mode,color=$000000)
addBlack(black,1,mode)
converttorgb24()
function addBlack(clip c, int num, string mode) {
clr = num * 256 + num + (num * 65536)
return (num > 255) ? c \
: addBlack(stackVertical(c,blankclip(width=400,height=1,pixel_type=mode,color=clr)),num+1,mode)
}
Da ist mir allerdings die Syntx nach wie vor ein Rätsel -
Vielleicht solltest du dir auch nochmal folgendes verinnerlichen:
über das skript wird eine Schnittliste erstellt, das skript wird also "von hinten" in eine Art Zugriffsbaumstruktur zerlegt und NICHT wie ein normales C/Basic-Programm "durchlaufen".
Die obigen Versuche sind eigentlich ziemliche Grenzfälle der skript-Sprache.
Da es sicher noch einige Lücken in der Fehlerbehandlung gibt, kann man grade bei rekursiven skripts schon mal einen crash erreichen.
Im obigen Beispiel fällt mir da folgendes auf.
(1) Die Zeile
StackHorizontal(clip1,Tweak(clip2,bright=counter))
heisst ja
last = StackHorizontal(clip1,Tweak(clip2,bright=counter))
Das wolltest du sicher nicht.(2) eine Funktion, die in der Schnittliste nicht gebraucht wird, wird auch nicht aufgerufen. Da "last" nie zurückgegeben wird, kommen deine Funktionen auch nicht zum Tragen.
(3) Ich glaube, jede user-Funktion muss einen Rückgabewert haben
-
Zitat
heisst ja
last = StackHorizontal(clip1,Tweak(clip2,bright=counter))
Hm, so aufgelöst aber ich das noch gar nicht betrachtet.
Aber wieso funktioniert dann das zweite Script? Das ist ja auch eine Rekursion, wenn auch anders aufgebaut.
Ich denke, ich werde die Sache nochmal neu beginnen. Die Ähnlichkeit der AVISynth-Syntax zu C scheint mich da in eine Sackgasse geführt zu haben.
Leider sind alle AVISynth-Anleitungen gerade auf diesem Gebiet nicht gerade sehr ergiebig.
Das Problem, was ich mit AVISynth generell noch habe ist, dass ich mich viel stärker auf AVISynth selbst konzentrieren muss als auf das eigentliche Problem.
Wie auch immer, ich habe ScriptClip und ConditionalReader "überlebt", dann schaffe ich das hier auch noch... irgendwann. -
das zweite script funktioniert, weil direkt im "return" bei jeder Bedingung ein clip zurückgegeben wird (durch das return wird das "last" sozusagen unterdrückt).
Ich glaube auch (da muss ich mal forschen)
- dass eine user-funktion einen Wert zurückgeben MUSS
- an eine Funktion wird alles (auch globale Variablen) nur byvalue (also als Kopie) übergegen. Man kanns daher in der Funktion nicht ändern. -
Haaalt, langsam ...
>> Ich glaube
>> - dass eine user-funktion einen Wert zurückgeben MUSSJup. Und wenn man nichts explizit zurückgibt, dann wird halt 'last' zurückgegeben:
function ABC(clip c) { c.filter() }
gibt auch ohne return() als Ergebnis c.filter() zurück.
>> - an eine Funktion wird alles (auch globale Variablen) nur byvalue (also als
>> Kopie) übergegen. Man kanns daher in der Funktion nicht ändern.Globale Variablen kann man sehr wohl ändern, sie müssen/brauchen/dürfen zu diesem Zweck auch gar nicht "übergeben" zu werden: sie sind ja global, also "immer present". z.B. in Restore24 gibt's reihenweise
global var=0
...
function juhuu( ) { global var = tralala }So richtig Sinn macht das aber nur bei Funktionen innerhalb der cond.environment, oder bei rekursiven Funktionen.
... oder Bei Spezialfällen wie z.B. den MVTools, die intern mit globalen Variablen arbeiten (wenn man eine Funktion hat, die Bewegungsvektoren sucht, sollte man per globalem Counter bei jedem Funktionsaufruf die idx-Variable um +1 erhöhen) :seher: -
Zitat
So richtig Sinn macht das aber nur ..... bei rekursiven Funktionen.
Genau deshalb habe ich's ja auch ohne Parameter, sondern mit globalen Variablen versucht. Und Rekursionen ohne globale Variablen... die kann ich mir nun wirklich nicht vorstellen. -
Wieso nicht? die folgende Rekursion läuft 10x durch, ganz ohne globale Variablen. (Macht zwar nichts wirklich sinnvolles, aber man kann ja andere Berechnungen dazwischenhängen) :
last.reccount(10)
function reccount(clip c, int counter) {
counter==0 ? c.subtitle(string(counter)) : c.reccount(counter-1) } -
Aha, wieder was gelernt.
Aber dann mal gleich die dumme Frage hinterher: Wie ist die Syntax, wenn ich z.B. bei count!=0 zwei Befehale abarbeiten lassen will, bei count==0 aber nur einen? Damit hatte ich nämlich auch so meine Probleme.
Ebenfalls (noch) unverständlich ist mit dieser clip c. Mit c und counter sind's ja zwei Variablen... verwirrend -
Zitat
Ebenfalls (noch) unverständlich ist mit dieser clip c. Mit c und counter sind's ja zwei Variablen... verwirrend
Clip c war hier nur deswegen drin, um überhaupt irgendwas sinnvolles zurückzugeben.
Hmmh ... anderes Beispiel: eine Zahl soll n-mal quadriert werden:CodeStartwert = 3wieoft_quadrieren = 5gesuchter_wert = quadriere_n_mal(Startwert, wieoft_quadrieren)function quadriere_n_mal(float base, int times) {base = base^2times == 1 ? base : quadriere_n_mal(base, times-1) }
ZitatWie ist die Syntax, wenn ich z.B. bei count!=0 zwei Befehale abarbeiten lassen will, bei count==0 aber nur einen?
Heheh, gut Frage. Je nach genauem Fall kann man's einfach hinschreiben, oder muss (wegen Avisynth's Grammatik) einen Trick bemühen:a) Sub-Funktionen erstellen
b) stickboy's Evaluate(String) - TrickCode
Alles anzeigen# Direkt hinschreiben: (keine Operation am Ende der Rekursion) # ------------------------------------------------------------ function recursive(int counter, float arbeitswert) { arbeitswert = tue_dieses( arbeitswert) arbeitswert = tue_jenes( arbeitswert) arbeitswert = tue_nochwas(arbeitswert) counter == 1 ? arbeitswert : recursive(counter-1, arbeitswert) } # Mit Ersatzfunktion: (zusätzliche Operation am Ende der Rekursion) # ----------------------------------------------------------------- function recursive(int counter, float arbeitswert) { arbeitswert = (counter==1) ? Rekursion_Ende(arbeitswert) \ : Rekursion_laeuft_noch(arbeitswert) counter == 1 ? arbeitswert : recursive(counter-1, arbeitswert) } function Rekursion_laeuft_noch(float arbeitswert) { arbeitswert = tue_dieses(arbeitswert) arbeitswert = tue_jenes(arbeitswert) arbeitswert = tue_folgendes(arbeitswert) return( arbeitswert ) } function Rekursion_Ende(float arbeitswert) { tue_wasganzanderes(Arbeitswert) } # Wie zuletzt, aber mit String(s): # -------------------------------- function recursive(int counter, float arbeitswert) { Rec_running = "arbeitswert = tue_dieses( arbeitswert) arbeitswert = tue_jenes( arbeitswert) arbeitswert = tue_nochwas(arbeitswert)" Rec_end = "arbeitswert = tue_wasganzanderes(arbeitswert)" (counter == 1) ? evaluate(Rec_end) : evaluate(Rec_running) (counter == 1) ? arbeitswert : recursive(counter-1, arbeitswert) }
edit: im String-Beispiel war etwas vertauscht ... jetzt stimmt's (hoffentlich).
Naja, ob's damit jetzt wirklich verständlicher geworden ist ... ? :hm:
Und dann ist da ja noch die Geschichte mit linksoffenen, rechtsoffenen, oder mittig geöffneten Rekursionen ...
/*graue-Haare-krieg'*/ -
Zitat
Clip c war hier nur deswegen drin, um überhaupt irgendwas sinnvolles zurückzugeben.
Also gewissermaßen ein Dummy.
Zitat
anderes Beispiel: eine Zahl soll n-mal quadriert werden:
DAS hab' ich jetzt sogar verstanden.
Zitat
a) Sub-Funktionen erstellen
OK, auf die Idee war ich bereits gekommen.
Zitat
b) stickboy's Evaluate(String) - Trick
Autsch!
Zitat
Naja, ob's damit jetzt wirklich verständlicher geworden ist ... ?
Einiges ja, natürlich bleibt dann noch genügend offen, was ich einfach testen muss, aber das hier ist schon mal eine Grundlage, auf der ich aufbauen kann, danke.
Zitat
Und dann ist da ja noch die Geschichte mit linksoffenen, rechtsoffenen, oder mittig geöffneten Rekursionen ...
ARGH! *totumfall* -
Um das Prinzip der Rekursion zu verstehen, muß man zunächst einmal das Prinzip der Rekursion verstanden haben.
*SCNR*
Ich habe mir schon ab und zu den Komfort einer richtigen Programmiersprache in AviSynth gewünscht. Gerade wenn man den Film nur als Ganzes bearbeitet (Filter) bzw. schneidet (trim), fallen die Unterschiede nicht so auf. Dann wundert man sich, daß manche Sachen einfach nicht gehen.
Zap
Jetzt mitmachen!
Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!