Schnelle Bildmanipulation: Das Pixel-Array
In den letzten beiden Abschnitt habe ich gezeigt, daß Processing.py zwar relativ schnell ist, aber 120.000 Operationen in einem Bildfenster doch eine gewisse Zeit benötigen. Falls man jedoch auf die Animation verzichten kann (und damit auf point()
oder get()
und set()
), geht es auch wesentlich schneller: Jedes Bild in Processing(.py) – und das schließt das Graphikfenster ein – wird intern als eine eindimensionale Liste der Farbwerte gespeichert. Die erste Position der Liste ist das erste Pixel links oben, die letzte Position folgerichtig das letzte Pixel rechts unten.
Ein pixels[]
-Array in Processing speichert in dieser Form die Farbwerte für jedes Pixels des Ausgabefensters. Um es zu initialisieren, muß vor der ersten Nutzung die Funktion loadPixels()
aufgerufen werden. Manipulationen im Pixel-Array werden erst sichtbar, wenn die Funktion updatePixels()
aufgerufen wird. loadPixels()
und updatePixels()
bilden so ein ähnliches Geschwisterpaar von Funktionen, wie zum Beispiel beginShape()
und endShape()
. Doch einen Unterschied gibt es: Wird das Pixel-Array nur zum Lesen der Farbwerte genutzt, muß updatePixels()
natürlich nicht aufgerufen werden. Da die Manipulationen eines Pixel-Arrays nur im Hauptspeicher des Rechners stattfinden, sind sie natürlich viel schneller als jede andere Processing-Funktion, die Bildinformationen manipuliert.
Da das Pixel-Array ein eindimensionales Array ist, muß auf die Zeilen und Spalten mit einem kleinen Trick zugegriffen werden. Jeder Punkt (x, y)
steht im Pixelarray an der Position x + (y*width)
. An die Farbwerte eines Pixels kommt man mit dem Aufruf
i = x + (y*width)
color(c) = pixels[i]
Die einzelnen Farbwerte im RGB-Raum kann man danach so auslesen:
r = red(c)
g = green(c)
b = blue(c)
Das Setzen eines Pixels erfolgt genau umgekehrt:
pixel[i] = color(r, g, b)
Natürlich kann man auch jeden anderen Farbraum (Graustufen, HSV), den Processing kennt, nutzen.
Fantastic Feather Fractal
Um zu zeigen, wie schnell die Manipulationen eines Pixel-Arrays sind, möchte ich wieder eine Iteration über 120.000 Schritte durchführen. Als Demonstrationsobjekt habe ich das Fantastic Feather Fractal gewählt, das Clifford A. Pickover in seinem Buch »Mazes for the Mind« vorgestellt hat. Wenn Ihr untenstehenden Quellcode laufen laßt, werdet Ihr feststellen, daß das fertige Fraktal fast unmittelbar nach dem Aufruf im Graphikfenster erscheint.1
Das Feather Fractal ist ein »seltsamer Attraktor«, ein Attraktor eines dynamischen Systems, das sich zwar chaotisch verhält, aber dennoch eine kompakte Menge ist, die es nie verläßt. Die Parameter des Sketches entstammen der oben genannten Quelle von Pickover, die Faktoren um das Ergebnis dem Bildfenster anzupassen habe ich durch wildes Herumexperimentieren gefunden2.
Der Quellcode
a = -.48
b = .93
def setup():
size(640, 480)
background(0)
colorMode(HSB, 255, 100, 100)
frame.setTitle("Fantastic Feather Fractal")
noLoop()
def draw():
loadPixels()
x = 4.0
y = .0
for i in range(1, 120000, 1):
x1 = b*y + f(x)
y = -x + f(x1)
x = x1
pixels[(350 + int(x*26)) + ((280 - int(y*26))*width)] = color(i%255, 100, 100)
updatePixels()
def f(x):
return a*x - (1.0 - a)*((2*(x**2))/(1.0 + x**2))
Wenn ich später noch auf Bildmanipulationen in Processing zurückkomme, werden die Pixel-Arrays noch einmal ausführlich behandelt werden.
Literatur
- Clifford A. Pickover: Mazes for the Mind. Computer s and the Unexpected, New York (St. Martin's Press) 1992. Das Buch gehört zu den Besten des umtriebigen Autors und da es aufgrund seines Alters antiquarisch für ein paar Cent zu bekommen ist, solltet Ihr zuschlagen. Das Feder-Fraktal ist auf den Seiten 33f. beschrieben, die über 400 anderen Seiten erfüllen fast jeden Traum eines an Computer-Experimenten interessierten Menschen.
- Florian Freistetter: Best of Chaos: Der seltsame Attraktor, Science Blogs (Astrodicticum Simplex) vom 4. Februar 2015 (Ich bin ein Fan von Florian Freistetter, er ist einer der wenigen guten deutschsprachigen Erklärbären für Naturwissenschaften)
-
Ich habe das Bild testweise auch mal erst nach 240.000 Schritten herausschreiben lassen. Die Verzögerung war kaum merkbar. Allerdings gab es auch nur noch einen geringen Unterschied zu dem Bild im Screenshot. Hier setzt die Auflösung des Ausgabefensters weiterem Erkenntnisgewinn Grenzen. ↩
-
Und das schon vor langer Zeit, als der Monitor meines Rechners noch eine Auflösung von 640 x 480 Pixeln hatte. 😜 ↩