Pixel Art & Bildbearbeitung mit Python

Hauptziele:

  1. Wichtigste Funktionalitäten der Numpy-Library anwenden können (v.a. Numpy-Arrays).
  2. Mit Jupyter-Notebook arbeiten können.
  3. Einfache Bildbearbeitungsfunktionen verstehen und programmieren.

Links:

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)$.

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`)

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.

Bild Original:

Flipped

Bildausschnitte I:

Bildausschnitte II:

Verpixeln:

Grayscale:

Black n' Write:

Sepia:

Invertieren:

Heller / Dunkler:

Kontrast erhöht:

Colors Andy Warhol-Style: Farbkanal isolieren Beispiel oben links (rot): Für alle Pixel werden R und G channels auf $0$ gesetzt.

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
  1. Erstelle auf GitHub ein neues Repo mit passendem Namen, z.B. „image_processing_python“.
  2. Gib das Repo den LPs frei (anschae / tkilla77).
  3. Füge alle Files, die du im Verlaufe dieses Themas erstellen/bearbeiten wirst unaufgefordert dem Repo hinzu.
  4. Commite und Pushe immer dann, wenn du Fortschritte gemacht hast.

Aufgabe 1: Numpy-Arrays

  1. Lade das Jupyter-Notebook numpy_tutorial.ipynb.zip herunter, entzippe es und füge es deinem Repo hinzu. Jupyter-Notebooks haben die Extension .ipynb.
  2. 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

  1. Erstelle ein Jupyter-Notebook pixel_art.ipynb im Repo und arbeite darin.
  2. Nehme das Array aus dem Beispiel zu "Pixel", also img = ... und zeige das Bild mit matplotlib an.
  3. Verändere es nun so, dass die italienische Flagge angezeigt wird (zu Ehren der Pizza und nicht Berlusconi):
  4. 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()

… das folgende Bild erzeugen:

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.

Farben

Tipps

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:

Animation

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.
  • talit/image_processing_python.txt
  • Zuletzt geändert: 2025-04-10 05:30
  • von hof