Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ws2122:asciia:ascii-animation.py [2022/03/16 15:20] Jaden |
ws2122:asciia:ascii-animation.py [2022/03/30 08:23] (aktuell) MoscarTU |
||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
===== ASCII-Animation.py ===== | ===== ASCII-Animation.py ===== | ||
+ | Diese Datei ist die Hauptdatei unseres Programms ASCIÌ-Animation. Sie muss ausgeführt werden, um das Programm zu starten. Neben der Main-Methode werden noch einige Hilfsfunktionen, unter anderem für eine kleine Benutzeroberfläche, implementiert. | ||
<code python> | <code python> | ||
import cv2 # muss extra installiert werden mit: pip install opencv-python | import cv2 # muss extra installiert werden mit: pip install opencv-python | ||
Zeile 11: | Zeile 11: | ||
import pyfiglet # muss extra installiert werden mit: pip install pyfiglet | import pyfiglet # muss extra installiert werden mit: pip install pyfiglet | ||
import colorama | import colorama | ||
- | from colorama import Fore, Back, Style # Diese und folgende Zeile für Farbänderung | + | from colorama import Fore, Back, Style |
colorama.init() | colorama.init() | ||
import threading | import threading | ||
Zeile 19: | Zeile 19: | ||
abh.Abbruchsignal() | abh.Abbruchsignal() | ||
</code> | </code> | ||
- | An dieser Stelle werden lediglich externe Bibliotheken und unsere Hilfsdateien importiert. | + | An dieser Stelle werden lediglich externe Bibliotheken und unsere Hilfsdateien importiert. Beachtet werden muss nur, dass cv2 (opencv), readchar und pyfiglet standardmäßig nicht bei Python installiert sind. |
<code python> | <code python> | ||
- | def Eingabepruefung(pruefe, ArtZahl): # Methode für korrekte Eingabe der Ja/Nein Abfragen, ArtZahl ist für welche Eingabe gemeint ist (beliebig erweiterbar) | + | # Methode für korrekte Eingabe der Ja/Nein Abfragen, ArtZahl ist für welche Eingabe gemeint ist (beliebig erweiterbar) |
+ | def Eingabepruefung(pruefe, ArtZahl): | ||
while True: | while True: | ||
if pruefe == "j" or pruefe == "n": | if pruefe == "j" or pruefe == "n": | ||
Zeile 36: | Zeile 37: | ||
pruefe = readchar.readkey().lower() | pruefe = readchar.readkey().lower() | ||
- | def FarbAnalyse(Farbe): # Methode für korrekte Eingabe der Farben | + | # Methode für korrekte Eingabe der Farben |
+ | def FarbAnalyse(Farbe): | ||
while True: | while True: | ||
if Farbe == "BLACK" or Farbe == "RED" or Farbe == "GREEN" or Farbe == "YELLOW" or Farbe == "BLUE" or Farbe == "MAGENTA" or Farbe == "CYAN" or Farbe == "WHITE": | if Farbe == "BLACK" or Farbe == "RED" or Farbe == "GREEN" or Farbe == "YELLOW" or Farbe == "BLUE" or Farbe == "MAGENTA" or Farbe == "CYAN" or Farbe == "WHITE": | ||
Zeile 43: | Zeile 45: | ||
Farbe = input("Das war keine gültige Farbe. Gib erneut eine Farbe ein: ").upper() | Farbe = input("Das war keine gültige Farbe. Gib erneut eine Farbe ein: ").upper() | ||
</code> | </code> | ||
- | Diese Methoden prüfen, ob die Nutzereingaben gültig sind und verlangen bei Ungültigkeit neue Eingaben. | + | Diese Methoden prüfen, ob die Nutzereingaben (zu Farbauswahl, Farben, Invertierung) gültig sind und verlangen bei Ungültigkeit neue Eingaben. |
<code python> | <code python> | ||
- | def LangsamesDrucken(text): # Methode für langsames Drucken der Buchstaben | + | # Methode für langsames Drucken der Buchstaben |
+ | def LangsamesDrucken(text): | ||
for a in text: | for a in text: | ||
print(a, end='') | print(a, end='') | ||
Zeile 51: | Zeile 54: | ||
time.sleep(0.08) | time.sleep(0.08) | ||
</code> | </code> | ||
- | Darstellung des Intro-Textes | + | Die Methode ist für das langsame Ausgeben der Buchstaben vom Intro-Text zuständig (Schreibmaschinenstil). |
<code python> | <code python> | ||
def BilderAusVideo(): # Wird mit neuem Thread gleichzeitg zum Konvertieren ausgeführt | def BilderAusVideo(): # Wird mit neuem Thread gleichzeitg zum Konvertieren ausgeführt | ||
Zeile 69: | Zeile 72: | ||
break | break | ||
</code> | </code> | ||
- | Diese Funktion sorgt dafür, dass das Generieren der ASCII-Frames und das Abspielen der schon berechneten Frames gleichzeitig passieren kann. | + | Diese Funktion ist für das Speichern der Frames aus dem Video zuständig. Weiter unten wird ein zusätzlicher Thread für die Methode ausgeführt, sodass das Umwandeln der Frames zu ASCII und die anschließende Ausgabe gleichzeitig passieren kann. |
<code python> | <code python> | ||
# main | # main | ||
Zeile 101: | Zeile 104: | ||
vorFarbe = "WHITE" | vorFarbe = "WHITE" | ||
hinFarbe = "BLACK" | hinFarbe = "BLACK" | ||
- | abh.AbbruchFarbeZuweisung (vorFarbe, hinFarbe) # Übertrag der Farbwerte zu Abbruch (für globale Variable) | + | |
+ | # Übertrag der Farbwerte zu Abbruch (für globale Variable) | ||
+ | abh.AbbruchFarbeZuweisung (vorFarbe, hinFarbe) | ||
</code> | </code> | ||
- | Anfang der Main-Methode, Einlesen der Datei, Abfrage der veränderlichen Eigenschaften (Invertierung, Farbwahl) | + | Das ist der Anfang der Main-Methode. Hier ist eine Benutzeroberfläche für das Einlesen der Videodatei und eine Abfrage der veränderlichen Eigenschaften (Invertierung, Farbwahl). |
<code python> | <code python> | ||
ordnerName = 'Bildercache' | ordnerName = 'Bildercache' | ||
Zeile 110: | Zeile 115: | ||
os.makedirs(ordnerName) | os.makedirs(ordnerName) | ||
</code> | </code> | ||
- | Erstellung des Bilderordners | + | Der Datei erstellt den Ordner für die Bilder, mit einem Fehlerabfang, falls dieser schon existiert. |
<code python> | <code python> | ||
cap = cv2.VideoCapture(videoname) | cap = cv2.VideoCapture(videoname) | ||
Zeile 116: | Zeile 121: | ||
fps = int(cap.get(cv2.CAP_PROP_FPS)) | fps = int(cap.get(cv2.CAP_PROP_FPS)) | ||
- | abc.UebertrageZuConverter(fps, booleanInvertierung) # übertragt FPS und Variable für Invertierung oder nicht (für globale Variable) | + | # übertragt FPS und Variable für Invertierung oder nicht (für globale Variable) |
+ | abc.UebertrageZuConverter(fps, booleanInvertierung) | ||
- | t1 = threading.Thread(target=BilderAusVideo, args=()) # Thread für fast gleichzeitiges Ausführen von Bilder aus Video und Konvertieren | + | # Thread für fast gleichzeitiges Ausführen von Bilder aus Video und Konvertieren |
+ | t1 = threading.Thread(target=BilderAusVideo, args=()) | ||
t1.start() # Thread Start | t1.start() # Thread Start | ||
</code> | </code> | ||
- | Einlesen der Videoinformationen | + | Hier werden die Videoinformationen verarbeitet und gespeichert. Außerdem startet hier der zusätzliche Thread mit der Methode "BilderAusVideo" (siehe oben). Dadurch passiert der Teil ab hier bis unten zum "t1.join()" parallel zu der Methode aus dem Threading. |
<code python> | <code python> | ||
Zeile 130: | Zeile 137: | ||
time.sleep(0.05) # 0.05 -> 5 Sekunden warten | time.sleep(0.05) # 0.05 -> 5 Sekunden warten | ||
</code> | </code> | ||
- | Ladebalken für die Vorlaufszeit | + | Hier ist ein Ladebalken für die Vorlaufszeit, damit erst ein paar Frames aus dem Video genommen werden, bevor das Umwandeln zu ASCII passiert. |
<code python> | <code python> | ||
- | print(getattr(Fore, vorFarbe) + getattr(Back, hinFarbe), end="\r") # für Hintergrundfarbe und Zeichenfarbe | + | # für Hintergrundfarbe und Zeichenfarbe |
- | # getattr ändert char/string in Attribut | + | print(getattr(Fore, vorFarbe) + getattr(Back, hinFarbe), end="\r") # getattr ändert char/string in Attribut |
- | for i in range (anzahlFrames): # Wandelt frames in ASCII um, bis alle Dateien umgewandelt wurden | + | |
+ | # Wandelt frames in ASCII um, bis alle Dateien umgewandelt wurden | ||
+ | for i in range (anzahlFrames): | ||
start = timeit.default_timer() | start = timeit.default_timer() | ||
abc.Umwandlung(i) | abc.Umwandlung(i) | ||
Zeile 146: | Zeile 155: | ||
t1.join() # Thread Ende bei erfolgreichen Abschließen der Schleifen | t1.join() # Thread Ende bei erfolgreichen Abschließen der Schleifen | ||
- | shutil.rmtree('Bildercache') # Löscht kompletten Cacheordner | + | shutil.rmtree('Bildercache') # Löscht kompletten Bildercache |
print(Style.RESET_ALL) | print(Style.RESET_ALL) | ||
</code> | </code> | ||
- | Umwandlung der Frames, Berechnung des Frame-Timings | + | Die for-Schleife geht alle Frames durch und ruft jedes mal die Datei "AsciiBildConverter" auf, in der ein "normales" Bild zu einem ASCII-Bild umgewandelt wird. Durch die for-Schleife werden die Bilder sehr schnell umgewandelt und auf der Konsole hintereinander ausgegeben, wodurch es wie ein Video aussieht. Dabei haben wir noch einen Timer implementiert, welcher die Zeit misst, damit die Videowiedergabe annähernd wie die vom Originalvideo ist. Allerdings ist das immer noch nicht optimal, weil die Berechnung dafür auch Mikrosekunden benötigt. |
+ | Am Programmende wird der Cache mit den Bildern gelöscht. | ||
+ | |||
+ | Tipp: Bei einer Pause oder am Ende des Programms die Anaconda hochscrollen, dadurch wird sichtbar, dass es wie ein "Daumenkino" ist. |