Pixel Art & Bildbearbeitung mit Python
Hauptziele:
- Wichtigste Funktionalitäten der Numpy-Library anwenden können (v.a. Numpy-Arrays).
- Mit Jupyter-Notebook arbeiten können.
- Einfache Bildbearbeitungsfunktionen verstehen und programmieren.
Links:
Theorie
Pixel
Ein Bild besteht aus lauter Pixel. Jedes Pixel wird durch vier Werte festgelegt: $$[R,G,B,A]$$ Also: Rot, Grün, Blau und Alpha. Jeder dieser Werte liegt im Bereich $0$ bis und mit $255$. Alpha gibt die Transparenz des Pixels an.
Ein Pixel, welches Rot in voller Stärke leuchten soll, wird also durch $[255,0,0,255]$ beschrieben.
Transparenz
Nicht alle Bildformate unterstützen Transparenz, das populäre JPEG-Format (*.jpg
) hat beispielsweise keinen Alpha-Kanal.
Im folgenden wird der Alpha-Kanal darum teilweise weggelassen, dann sind die Pixel nicht transparent, ein Bildpunkt besteht nur aus drei statt vier Werten.
Beispiel
Betrachte das folgende Bild:
Es besteht aus $2 \times 3$, also insgesamt $6$ Pixel. In Python wird dieses Bild durch das folgende Numpy-Array beschrieben:
img = np.array( [[[255,0,0,255], # red [0,255,0,255], # green [0,0,255,255]], # blue [[255,0,255,255], # pink [255,255,255,255], # white [0,0,0,255]]] # black )
Dieses Arrays ist also ein 3D-Array mit Shape (img.shape
) $(2, 3, 4)$.
Bilder einlesen, anzeigen und speichern
Der folgende Code liest das Bild input_image.png
(im gleichen Ordner wie Python-File) ein und speichert es unter dem Namen output_image.png
. Achtung: Das Bild output_image.png
wird bei jedem Ausführen überschrieben.
import numpy as np from skimage import io # to read image import matplotlib.pyplot as plt # to show (and save) image import copy img_org = io.imread('input_image.png') # read image, is stored as numpy-array in variable img # make copy of image before you manipulate it img = copy.deepcopy(img_org) # here can manipulate img pass # show image plt.axis('off') # Turn off axis ticks and labels plt.tight_layout(pad=0) # Remove padding around the image plt.imshow(img) # For color images plt.show() # save image plt.savefig(`output_image.png`)
Bild mit Code zeichnen
Möchtest du einen Code schreiben, der dir ein Bild zeichnet? Dann ist es eine gute Idee, mit einem mit lauter Nullen gefüllten Numpy-Array mit der richtigen Dimension anzufangen:
img = np.zeros((32,64,4),dtype=int)
- Die erste Zahl gibt die Anzahl Pixel in vertikale Richtung ($y$) an.
- Die zweite Zahl gibt die Anzahl Pixel in horizontale Richtung ($x$) an.
- Die dritte Zahl gibt an, dass für jedes Pixel $4$ Werte (RGB und Alpha) benötigt werden.
dtype=int
stellt sicher, dass im Array nur ganze Zahlen (integers) und keine Nachkommazahlen stehen. Ohne dies kann man die Transparenz (Alpha) nicht einstellen.
Bildbearbeitung
Colors Andy Warhol-Style: Farbkanal isolieren
Beispiel oben links (rot): Für alle Pixel werden R und G channels auf $0$ gesetzt.
Aufgaben
Aufgaben A: Pixel Art
Aufgabe 0
Installieren
- Installiere die Jupyter Extension von Microsoft in VSCode
- Installiere die benötigten Python Module (pip Befehl muss ev. angepasst werden):
pip install numpy pip install scikit-image pip install matplotlib
Falls dies nicht funktioniert, probiere (passe e.v. Python Version an!!!)
py -3.11 -m pip install numpy py -3.11 -m pip install scikit-image py -3.11 -m pip install matplotlib
Git-Repo
- Erstelle auf GitHub ein neues Repo mit passendem Namen, z.B. „image_processing_python“.
- Gib das Repo den LPs frei (
anschae
/tkilla77
). - Füge alle Files, die du im Verlaufe dieses Themas erstellen/bearbeiten wirst unaufgefordert dem Repo hinzu.
- Commite und Pushe immer dann, wenn du Fortschritte gemacht hast.
Aufgabe 1: Numpy-Arrays
- Lade das Jupyter-Notebook numpy_tutorial.ipynb.zip herunter, entzippe es und füge es deinem Repo hinzu. Jupyter-Notebooks haben die Extension
.ipynb
. - Arbeite es dann durch. Die notwendige Theorie dazu findest du im Numpy-Tutorial hier. Falls du etwas nicht verstehst, kannst du es dir z.B. von ChatGPT erklären lassen.
Aufgabe 2: Fun with Flags
- Erstelle ein Jupyter-Notebook
pixel_art.ipynb
im Repo und arbeite darin. - Nehme das Array aus dem Beispiel zu "Pixel", also
img = ...
und zeige das Bild mit matplotlib an. - Wähle nun eine schöne (und einfache) Flagge und zeichne sie selbst mithilfe eines Numpy-Arrays.
Aufgabe 3: Pixel Art
In der letzten Aufgabe hast du gesehen, dass es ziemlich mühsam ist, mit einem Numpy-Array ein Bild zu designen. Je grösser das Bild sein soll, desto schlimmer wird es. Wir wollen deshalb eine Funktion schreiben, die es uns erlaubt, auf einfache Art und weise ein Pixel Art Bild zu zeichnen.
Teil I
Schreibe deshalb eine Funktion create_pixel_img_from_str(img_str)
, die eine Liste mit Strings, die das Bild beschreiben, entgegennimmt. Sie generiert dann das entsprechende Numpy-Array und gibt es zurück.
Zum Beispiel soll der Code …
img_str = [ " rrrrr ", " rrrrrrrrr ", " kkkssks ", " ksksssksss ", " kskksssksss ", " kksssskkkk ", " sssssss ", " bbrbbb ", " bbbrbbrbbb ", " bbbbrbbrbbbb ", " ssbbrrrrbbss ", " sssryrryrsss ", " ssrrrrrrrrss ", " rrr rrr ", " kkk kkk ", " kkkk kkkk ", ] img = create_pixel_img_from_str(img_str) plt.axis('off') plt.tight_layout(pad=0) plt.imshow(img) plt.show()
Die Buchstaben stehen für die verschiedenen Farben, z.B. 'r' für Rot, 'y' für Gelb (Yellow), 's' für Haut (Skin). Ein Leerschlag steht für transparent ($[0,0,0,0]$). Es lohnt sich aber, den Code so zu schreiben, dass er eine Vielzahl an Farben beinhaltet. Du kannst gerne meine Farben übernehmen, diese abändern und weitere hinzu fügen.
Teil II
Mache damit tolle Pixel Art!
Aufgabe 4: GIF-Animation (Optional)
Erstelle mehrere Pixel Images wie in der Aufgabe vorher und animiere diese. Speichere sie dann als GIF.
Der folgende Code dient als Inspiration:
Aufgaben B: Bildbearbeitung
Aufgabe B1
- Gruppenarbeit (2-3 Personen)
- ohne Computer, Papier
- wird ein Bildbearbeitungseffekt zugeteilt
- überlegt euch, wie man dies umsetzen kann
Einfache Effekte:
- Farbkanal isolieren (Andy Warhol)
- Invertieren
- Flippen / Spiegeln
- Bildausschnitt
- Verpixeln
- (Black n' White)
Aufgabe B2
Programmiere mind. zwei dieser Effekte. Mache es selbst und ohne direkte Hilfe (z.B. von ChatGPT).
Hole dir Hilfe nur für allgemeine Fragen. Prompt in ChatGPT darf nicht sein „Wie invertiere ich ein Bild in Python“, sondern sollte sein „Wie kann ich ein Numpy Array erstellen?“
Aufgabe B3 (optional)
Überlege dir andere oder eigene Effekte, probiere aus, sei kreativ und erstelle damit neue Versionen eine Bilds (z.B. der Grumpy Cat).
Aufgabe B4: Eigenes Bildbearbeitungsprogramm (optional)
Programmiere ein eigenes Bildbearbeitungsprogramm mit einer graphischen Oberfläche, welches folgendes kann:
- Open-Button: Kann Bild laden
- dieses wird angezeigt
- einige Effekte, die man anwählen und einstellen kann, z.B. mit:
- Checkboxes
- Sliders
- bearbeitetes Bild wird angezeigt, in real time updated
- Save-Button: bearbeitetes Bild speichern
Tipps:
- Verwende dazu eine Python-Library für das Erstellen von GUI, wie z.B. PyQT.
- Verwende z.B. ChatGPT um das Grundgerüst des GUI zu erstellen.