Zum Inhalt springen
BetaEN
Lektion 3 von 5Informatik entdecken

Informatik entdecken · Lektion 3 · 40 Minuten

Bilder bestehen aus Pixeln

Das lernst du

  • Ein Bild als Liste von Zeilen mit Helligkeitswerten speichern
  • Verstehen, wie Farben aus Rot, Grün und Blau entstehen
  • Eigene Bildfilter programmieren

Ein Bild ist eine Tabelle aus Zahlen

Zoomst du ganz nah an ein Foto heran, siehst du kleine Quadrate: Pixel. Jedes Pixel hat genau eine Farbe. Für den Computer ist ein Bild deshalb nur eine große Tabelle aus Zahlen.

Am einfachsten ist ein Graustufen-Bild: Jedes Pixel ist eine Zahl von 0 (schwarz) bis 255 (weiß) – genau ein Byte. In Python ist das eine Liste von Zeilen. Wir zeigen es mit dem Spiele-Modul an:

from codelix import spiel

bild = [
    [255, 255, 200, 200, 200, 200, 255, 255],
    [255, 200, 200, 200, 200, 200, 200, 255],
    [200, 200, 0, 200, 200, 0, 200, 200],
    [200, 200, 200, 200, 200, 200, 200, 200],
    [200, 60, 200, 200, 200, 200, 60, 200],
    [200, 200, 60, 60, 60, 60, 200, 200],
    [255, 200, 200, 200, 200, 200, 200, 255],
    [255, 255, 200, 200, 200, 200, 255, 255],
]


def zeigen(bild, x0=0, groesse=20):
    for y, zeile in enumerate(bild):
        for x, grau in enumerate(zeile):
            spiel.rechteck(x0 + x * groesse, y * groesse, groesse, groesse, f"rgb({grau},{grau},{grau})")


spiel.fenster(160, 160)
zeigen(bild)
print("Breite:", len(bild[0]), "Höhe:", len(bild))

bild[2][2] ist das Pixel in Zeile 2, Spalte 2 – das linke Auge. Ändere eine Zahl und schau, was passiert.

Farben aus drei Zahlen

Ein Farbbild speichert für jedes Pixel drei Zahlen: wie viel Rot, Grün und Blau es enthält, jeweils von 0 bis 255. Aus diesen drei Farben mischt der Bildschirm alle anderen:

from codelix import spiel

farben = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255), (255, 255, 255)]
spiel.fenster(360, 120)
for nummer, (r, g, b) in enumerate(farben):
    spiel.rechteck(nummer * 60, 0, 60, 60, f"rgb({r},{g},{b})")
    grau = round(0.299 * r + 0.587 * g + 0.114 * b)
    spiel.rechteck(nummer * 60, 60, 60, 60, f"rgb({grau},{grau},{grau})")
    print((r, g, b), "→ Graustufe", grau)

Unten siehst du dieselben Farben in Graustufen. Grün wirkt viel heller als Blau – so empfindet es auch dein Auge. Deshalb zählt Grün in der Formel am meisten.

Ein Filter verändert jedes Pixel

Ein Bildfilter geht durch alle Pixel und rechnet für jedes einen neuen Wert aus. Dieser Filter macht das Bild heller. Mit min(255, …) bleibt jeder Wert im erlaubten Bereich:

from codelix import spiel

bild = [
    [0, 40, 80, 120],
    [40, 80, 120, 160],
    [80, 120, 160, 200],
    [120, 160, 200, 240],
]


def heller(bild, plus):
    neu = []
    for zeile in bild:
        neu.append([min(255, wert + plus) for wert in zeile])
    return neu


def zeigen(bild, x0=0, groesse=30):
    for y, zeile in enumerate(bild):
        for x, grau in enumerate(zeile):
            spiel.rechteck(x0 + x * groesse, y * groesse, groesse, groesse, f"rgb({grau},{grau},{grau})")


spiel.fenster(260, 120)
zeigen(bild)
zeigen(heller(bild, 80), 140)

Links das Original, rechts das hellere Bild. Genau so funktionieren die Filter in Foto-Apps – nur mit Millionen Pixeln statt 16.

Weiterbauen: Wenn deine Aufgabe klappt: Probiere deine Filter am Smiley aus. Oder programmiere einen Spiegel-Filter (jede Zeile umdrehen mit zeile[::-1]) oder einen Weichzeichner, der jedes Pixel durch den Durchschnitt mit seinen Nachbarn ersetzt.

Deine Aufgabe

Jetzt bist du dran

Schreib zwei Bildfilter für Graustufen-Bilder (Listen von Zeilen mit Werten von 0 bis 255). invertieren(bild) macht ein Negativ: Aus jedem Wert w wird 255 - w. schwarz_weiss(bild, grenze) macht jeden Wert ab grenze zu 255 (weiß) und alle kleineren zu 0 (schwarz). Beide geben ein neues Bild zurück und lassen das alte unverändert.

bild = [
    [0, 60, 120, 180],
    [60, 120, 180, 240],
]


def invertieren(bild):
    neu = []
    return neu


def schwarz_weiss(bild, grenze):
    neu = []
    return neu


print(invertieren(bild))
print(schwarz_weiss(bild, 128))

Ohne Hinweise gelöst gibt es einen ⭐ auf deiner Fortschrittsseite.

Lösung anzeigen

Versuch es erst selbst – aus Fehlern lernt man am meisten. Hier ist eine mögliche Lösung:

bild = [
    [0, 60, 120, 180],
    [60, 120, 180, 240],
]


def invertieren(bild):
    neu = []
    for zeile in bild:
        neu.append([255 - wert for wert in zeile])
    return neu


def schwarz_weiss(bild, grenze):
    neu = []
    for zeile in bild:
        neu.append([255 if wert >= grenze else 0 for wert in zeile])
    return neu


print(invertieren(bild))
print(schwarz_weiss(bild, 128))