Bildabtaster
Wiederholung Array
In der letzten Woche waren Arrays das Thema. Arrays sind immer das Werkzeug der Wahl, wenn man mehrere Informationen in einer Liste zusammenhalten möchte.
Heute wollen wir dieses erarbeitete Wissen nutzen, um die Bilder, die ihr in Woche vier gemacht habt, im ersten Schritt zu laden, bevor wir sie im Anschluss anzeigen und analysieren werden.
Wenn es noch grundsätzliche Fragen zum Thema Arrays gibt, solltet ihr den Beitrag der Vorwoche noch einmal lesen oder im Buch „Learning Processing“ das Kapitel 9. Die nächsten Schritte werden darauf aufbauen.
Bilder laden
Um ein Bild zu laden, definiert man zu erst eine Variable vom Typ PImage. In der setup()-Methode wird der Ladevorgang gestartet und mit der Variable verknüpft.
Beispiel:
// Instanzname für das Bild PImage img;
Bilder anzeigen
Um ein Bild anzuzeigen verwendet man den Befehl image(), wobei dieser mindestens die Angabe von drei Paramatern benötigt. Zu erst den Namen der Variable, sprich das Bild, dass angezeigt werden soll, und dann die Startposition in Form von x und y. Optional kann man als vierte und fünfte Parameter die gewünschte Bildbreite und Bildhöhe in Pixeln angeben.
Beispiel:
// Bild laden img = loadImage( "1.jpg" );
Bilder analysieren
Uns ist aus Programmen wie Photoshop bekannt, dass ein Bild aus einzelnen Pixeln besteht. Den Farbwert eines Pixels kann man zum Beispiel mit der Pipete bestimmen, indem man die gewünschte x und y Koordinate ansteuert.
Die Pixelinformationen eines Bildes werden in Processing in einem eindimensionalen Array gehalten. Eindimensional heißt, das Reihe für Reihe hintereinander gespeichert wird. Hat ein Bild eine größe von 400 x 300 Pixel, so werden erst die 400 Pixel der ersten Reihe gespeichert, bevor ab Index 400 die zweite Reihe abgespeichert wird.
Verändern der Pixel
Damit man auf das Pixel-Array zugreifen kann, muss man mit dem Befehl myImg.loadPixels() die Pixel laden.
Um den Farbwert eines Pixels zu verändern, nutzt man einfach den gewünschten Index und beschreibt dieses mit einer neuen Farbe.
Beispiel:
pixels[ 20 ] = color( 200, 100, 20 );
Um direkte Änderungen der Pixelwerte auch visuell zu sehen, muss man am Schluss die Funktion updatePixels() aufrufen, die bewirkt das die Ansicht auf Basis der neuen Pixeldaten aktualisiert wird.
Bild abtasten
Um einen Eindruck von den verwendeten Farben eines Bildes zu erhalten, kann man das Bild jetzt Spalte für Spalte und Reihe für Reihe abtasten. Dieses Abtasten muss nicht Pixel für Pixel erfolgen, sondern für unseren Zweck reicht es erst einmal, wenn man sich ein 3 x 3 oder 4 x 4 großes Schachbrett imaginär über dem Bild vorstellt.
Diese einzelnen Felder tastet man jetzt ab und liest an den 9 bzw. 16 Positionen die Farbwerte aus und speichert sie in einer Liste ab.
Das passende Werkzeug dafür berechnet uns auf Basis der aktuellen Spalte und Reihe den Index in der Liste mit den Pixeln. Aber um das Raster wie gewünscht abzutasten benötigen wir im Vorfeld einige Berechnungen.
Zu erst legt man fest, wie viele Reihen und Spalten maximal gewünscht sind. Um diese Anzahl zu erreichen benötigt man zwei Zählvariablen.
Beispiel:
// Max-Anzahl der Reihen & Spalten definieren int rowMax = 3; int columnMax = 4; // Zählvariablen erstellen int rowCount = 0; int columnCount = 0;
Nun erstellt man die eigentliche Methode, die als Parameter ein Bild erwartet und anstelle des bekannten Rückgabewert void() eine Liste von Farben zurück gibt. Eine bekannte Funktion mit Rückgabewert ist zum Beispiel random() oder noise().
Beispiel:
// Funktion um Farbstimmungen aus einem Bild zu extrahieren color[] extractColor( PImage img ) { }
Innerhalb der Methode definiert man die Reihenhöhe und Spaltenbreite, indem man die Bildhöhe durch die Reihenanzahl und die Bildbreite durch die Spaltenanzahl dividiert. Diese beiden errechneten Werte sind die Abstände für die Abtastrate.
Beispiel:
// Berechnung der Reihen- und Spaltenbreite int rowHeight = img.height / rowMax; int columnWidth = img.width / columnMax;
Bevor das Bild schachbrettartig abgetastet wird, erstellt man noch eine Liste, in die man so viele Farben eintragen kann, wie man oben über die Maximal-Werte für die Reihe und Spalte definiert hat. Zusätzlich benötigt man noch einen Zeiger auf den aktuellen Index in der Liste, in diesem Fall die Variable listIndex.
Zum schachbrettartigen Abtasten verwenden wir zwei verschachtelte while-Schleifen, die bereits in Woche 2 Thema waren. Wichtig ist dabei, dass in der inneren Schleife der Spaltenzähler um eins erhört wird und in der äußeren Schleife wieder auf 0 gesetzt wird und der Reihenzähler um eins erhöht wird. Den Listen-Index erhöht man ebenfalls in der inneren Schleife.
![]()
Beispiel:
// Verschachelte while-Schleifen while( rowCount < rowMax ) { while( columnCount < columnMax ) { listIndex++; columnCount++; } columnCount = 0; rowCount++; }
Im inneren Bereich muss jetzt der Index für die Pixelliste berechnet werden. Zuerst berechnet man den Index in der Spalte, dann den Index in der Reihe. Wichtig bei der Positionsbestimmung in der eindimensionalen Liste ist, dass bei der Berechnung der Index der Reihe mit der Bildbreite multipliziert wird.
Der letzte Schritt ist dann das Abspeichern der Farbwerte in der Farbliste. Das kann entweder direkt über colorList[ listIndex ] = img.pixels[ index ] erfolgen, oder man nutzt die Helferfunktionen red(), green() und blue() und speichert die Werte zwischen.
Hausaufgabe
Die nächsten zwei Wochen stehen im Zeichen der Zwischenpräsentation. Dazu solltet ihr auf jeden Fall noch einmal die Kapitel 1, 2, 3, 4 aus dem Buch Learning Processing durcharbeiten.
Am 13.05. hat dann jeder 5 Minuten Zeit seine Arbeit und deren Entstehungsprozess zu präsentieren.
Informationen zum Dateiformat, der Bezeichnung und zum Upload der Dateien sind unter dem Punkt Prüfungsleistung zu finden.
Die Beispiele der Woche können hier herunter geladen werden.