Netpbm-Tools und Shell-Skripte

Aus LinuxUser 09/2002

Netpbm-Tools und Shell-Skripte

Auf Kommando animiert

Grafikbearbeitung muss nicht zwangsläufig mit der Maus erfolgen. Mit den Filtern des Netpbm-Pakets und “Verwandten” lassen sich Arbeitsschritte per Shell-Skript automatisieren.

Pixelbasierte Grafikformate gab es schon vor Jahren zuhauf. Entsprechend oft wurden und werden passende Konvertierungsprogramme benötigt. Will man diese Aufgabe nach Unix-Art mit einzelnen Filterprogrammen für die Kommandozeile lösen, so müsste man für n Grafikformate genau (n-1)@L: *n Filter schreiben. Nimmt man stattdessen ein Zwischenformat hinzu, so braucht es nur noch n Filter, die von den verschiedenen Grafikformaten in das Zwischenformat konvertieren und weitere n, die vom Zwischenformat in die Grafikformate zurück wandeln.

Mit dieser Idee begann Jef Poskanzer 1989 seine Arbeit an den pbmtools. Bis 1994 kamen Schritt für Schritt neue Formate und Effektfilter für das Zwischenformat zur Sammlung dazu, die inzwischen unter dem Namen netpbm firmiert. Seit dem Jahr 2000 geht die Netpbm-Entwicklung wieder aktiv voran; das Projekt ist auf Sourceforge beheimatet.

Bit, Grey oder Pix?

Genaugenommen gibt es nicht nur eines, sondern drei Zwischenformate in Netpbm: “Portable Bitmap” (PBM), “Portable Greymap” (PGM) und “Portable Pixmap” (PPM). Das PBM-Format kennt nur gesetzte (schwarze) und nicht gesetzte (weiße) Pixel und kommt deshalb mit einem Bit pro Pixel aus. Das PGM-Format kann nur Graustufen speichern und verwendet dafür im Normalfall acht Bit pro Pixel (256 Graustufen). Das PPM-Format sieht 24 Bit pro Pixel vor (jeweils acht Bit für die Grundfarben Rot, Grün und Blau), was 16,7 Millionen Farben (“True Color”) ergibt. Ist irgendeins der drei Zwischenformate gemeint, spricht man von “Portable Anymap” (PNM).

Filter, die von Fremdformaten ins Zwischenformat konvertieren, heißen etwa tgatoppm, giftopnm oder g3topbm. Für die umgekehrte Richtung sind zum Beispiel ppmtogif, pnmtotiff oder pnmtops zuständig. Dazu kommen Filter, die ausschließlich auf den Zwischenformaten arbeiten. So wandelt ppmtopgm in Graustufen um, pnmsmooth rechnet unscharf, und pgmnorm normiert Graustufen.

Quellmaterial

Für die Bildbearbeitung braucht es natürlich Ausgangsmaterial, das es kommandozeilengesteuert zu verwursten gilt. Auch die Erzeugung dieser Bilder kann der Rechner erledigen, und zwar mit dem freien Raytracer Povray. Die Szenenbeschreibungsdatei glass.pov aus Listing 1 veranlasst das Programm dazu, ein Bild mit fünf gläsernen Kugeln vor einem karierten Hintergrund zu berechnen. Mit der clock-Variable kann zusätzlich der Hintergrund für eine simple Animation bewegt werden.

Listing 1

glass.pov

// Glaskugel-Animation
// (C) 7/2002 Christian Perle (POVaddict) / LinuxUser
// Kamera
camera {
  location <0, 0, -10>
  direction <0, 0, 4>
  look_at <0, 0, 0>
}
// Beleuchtung
light_source { <10, 10, -10> color rgb<1, 1, 1> }
// Deklaration der Glaskugel
#declare GKugel = sphere {
  <0, 0, 0>, 0.5
  scale <1, 1, 0.5>
  finish { phong 0.7 reflection 0.1 refraction 1 ior 1.33 }
}
// Fuenf farbige Glaskugeln
object {
  GKugel
  translate <-1, -0.6, 0>
  pigment { rgbf<1, 0.7, 0.7, 0.7> }
}
object {
  GKugel
  translate <0, 0, 0>
  pigment { rgbf<.7, 1, .7, .7> }
}
object {
  GKugel
  translate <1, 0.6, 0>
  pigment { rgbf<0.7, 0.7, 1, 0.7> }
}
object {
  GKugel
  translate <1, -0.6, 0>
  pigment { rgbf<1, 0.7, 1, 0.7> }
}
object {
  GKugel
  translate <-1, 0.6, 0>
  pigment { rgbf<0.7, 1, 1, 0.7> }
}
// Schachbrettmuster im Hintergrund
plane {
  <0, 0, -1>, -4
  pigment {
    checker color rgb<0.5, 0.5, 0.5>, rgb<1, 1, 1>
    translate <-clock, -clock, 0>
    scale 0.4
  }
  finish { ambient 0.4 }
}

Diese Datei werfen wir Povray in der Version 3.0 oder 3.1. zum Fraß vor. Das Programm soll ein 320 mal 240 Pixel großes Bild erzeugen, Anti-Aliasing verwenden und praktischerweise gleich das PPM-Format zur Ausgabe verwenden:

povray +i glass.pov +w320 +h240 +a0.1 +fp +v

Abbildung 1 zeigt das Ergebnis, das in der Datei glass.ppm gespeichert ist.

Abbildung 1: Glaskugeln als Testbild

Abbildung 1: Glaskugeln als Testbild

Filter in Ketten

Die folgenden Arbeitsschritte verfremden das Testbild mit einigen Filterkommandos. Zuerst wandelt folgender Befehl das Bild in Graustufen:

ppmtopgm glass.ppm > glass.pgm

Wie jeder andere Filter aus dem Netpbm-Paket schreibt ppmtopgm das Ergebnis auf die Standardausgabe, die wir mit dem Größer-als-Zeichen > in eine neue Datei glass.pgm umleiten. Das Ergebnis zeigt Abbildung 2.

Abbildung 2: Plötzlich ist alles grau

Abbildung 2: Plötzlich ist alles grau

Um für weitere Filterschritte unnötige Temporärdateien zu vermeiden, nutzen wir nun aus, dass die Netpbm-Programme von der Standardeingabe lesen können. Damit ist es möglich, mehrere Filter mit Pipes in der Shell hintereinander zu schalten:

ppmtopgm glass.ppm | pgmoil -n 5 | pgmtoppm Blue-White > oil.pgm

Die Ausgabe von ppmtopgm wird dabei direkt an pgmoil weiter gereicht. Dieser Filter versieht das Bild mit einem Effekt, der die Konturen wie in einem Ölbild verlaufen lässt. Die pgmoil-Option -n 5 teilt dem Filter mit, den Öl-Effekt auf Felder von je 5 mal 5 Pixeln anzuwenden.

Um wieder Farbe ins Bild zu bringen, reiht sich ein weiterer Filter (pgmtoppm) in die Kette ein, der die Graustufen auf einen Blau-Weiß-Verlauf abbildet. Das Resultat sehen Sie in Abbildung 3.

Abbildung 3: "Blaupause", Öl auf TFT, 2002

Abbildung 3: “Blaupause”, Öl auf TFT, 2002

Laufen lernen

Einzelne Filter von der Kommandozeile aus aufzurufen ist zwar ganz nett, doch viele Stärken der Kommandozeilentools nutzen erst Shell-Skripte richtig aus. Damit können Sie in einem Rutsch ganze Sammlungen von Bilddateien durch die gleiche Filterkette schicken oder einfach nur in ein anderes Format bringen.

Doch woher die Bilderflut nehmen? Auch hier hilft Povray mit dem bereits angesprochenen Animationsfeature. Mit dem Kommando

povray +i glass.pov +w240 +h180 +fp +a0.1 +kfi00 +kff49 +kc

bringen Sie den Raytracer dazu, eine Animationssequenz von 50 Bildern zu berechnen. Die Bilddateien heißen glass00.ppm, glass01.ppm bis glass49.ppm. Entsprechend stehen die Optionen +kfi und +kff für die Nummern des ersten bzw. letzten Bildes. Die Option +kc zeigt an, dass es sich um eine zyklisch wiederholte Animation handelt.

Nun soll aus den Einzelbildern ein animiertes GIF-Bild zum Einbau in eine Web-Seite entstehen. Damit die GIF-Datei nicht zu groß wird, bietet sich eine Verkleinerung der Bildabmessungen auf 100 mal 75 Pixel an. Das Shell-Skript mkgifanim (Listing 2) bewältigt diese Aufgabe und ruft abschließend das Tool whirlgif auf, das die GIF-Einzelbilder zum animierten GIF zusammenklebt.

Listing 2

mkgifanim

#!/bin/bash
for f in glass??.ppm
do
  pnmscale -w 100 $f | ppmquant 256 | ppmtogif > ${f%.ppm}.gif
done
whirlgif -o g_anim.gif -loop -time 8 glass??.gif

In der for-Schleife durchläuft die Variable f alle Dateinamen, die auf das Shell-Muster (siehe Kasten 1) glass??.ppm passen. In der Filterkette skaliert pnmscale das jeweilige Bild auf 100 Pixel Breite. Die Höhe wird entsprechend dem Seitenverhältnis mitskaliert. Den nächsten Schritt besorgt ppmquant, das die Farbanzahl auf die für GIF maximalen 256 Farben reduziert. Schließlich schreibt ppmtogif das eigentliche GIF-Bild. Den neuen Dateinamen konstruiert das Skript dabei aus dem aktuellen Inhalt der Variable f, wobei es .ppm als Endung abschneidet und .gif als neue Endung anhängt. Der nachfolgende whirlgif-Aufruf erzeugt die Animation g_anim.gif, die durch die Option -loop endlos wiederholt wird und durch -time 8 zwischen den Bildern 8 Millisekunden Pause lässt. In Abbildung 4 sehen Sie die Animation, wenn Sie dieses Heft mit Daumenkino-Plugin gekauft haben. Im Ernst: Die Datei befindet sich auch auf der Heft-CD und lässt sich in einem Web-Browser oder xanim betrachten.

Abbildung 4: Animation

Abbildung 4: Animation

Kasten 1: Shell-Muster

Die Shell kennt bestimmte Muster für Datei- und Verzeichnisnamen, die sie vor dem Aufruf des entsprechenden Kommandos expandiert. Die wichtigsten sind

  • das Fragezeichen ?. Es steht für genau ein beliebiges Zeichen.
  • der Stern *. Er dient als Joker für beliebig viele (auch null) beliebige Zeichen.
  • Zeichenaufzählungen in eckigen Klammern []. An der entsprechenden Stelle muss genau eines der umklammerten Zeichen stehen. Dabei gibt es verschiedene Schreibweisen, die die folgenden Beispielen verdeutlichen: Das Muster lx[acE].txt passt auf die Namen lxa.txt, lxc.txt und lxE.txt.
  • graph[a-z][0-9][0-9].jp? passt (unter anderem) auf die Namen graphi50.jpg, grapho01.jpg und graphx55.jpe. Der Bindestrich innerhalb der eckigen Klammern sorgt dafür, dass ein ganzer Zeichenbereich gemeint ist, also alle Kleinbuchstaben von a bis z bzw. alle Ziffern von 0 bis 9.

Das Muster [^abc][xyz].b* passt (unter anderem) auf wy.b und 3x.ball, aber nicht auf cz.bmg oder rx.img. Das Dach ^ nach der einführenden Klammer steht für Negation, gemeint sind also alle Zeichen außer den nachfolgend aufgelisteten.

Effekte animieren

Neben GIF gibt es weniger patentbelastete Animationsformate wie MPEG und FLI. xanim zeigt auch letzteres an. Für die mkedge-Animation aus Listing 3 brauchen wir ppm2fli, das nicht Teil der Netpbm-Tools ist.

Listing 3

mkedge

#!/bin/bash
for f in glass??.ppm
do
  ppmtopgm $i | pgmedge | pgmnorm > ${i%.ppm}.pgm
done
ls glass??.pgm > frames.list
ppm2fli -g240x180 frames.list edge_anim.fli

Das Skript durchläuft wiederum alle Einzelbilder der Glaskugel-Sequenz, wandelt sie in Graustufen (ppmtopgm), erzeugt eine Liniendarstellung der Kanten im Bild (pgmedge) und normiert die Helligkeitsverteilung (pgmnorm). Die Ergebnisbilder erhalten die Dateinamen glass00.pgm bis glass49.pgm. Da ppm2fli die Liste der Einzelbilder in einer Datei erwartet, muss das ls-Kommando diese Liste zunächst erzeugen, bevor der eigentliche ppm2fli-Lauf starten kann. Auch die Abmessungen der Bilder müssen Sie dem Tool durch die Option -g mitteilen.

Für die Erzeugung einer weiteren Animation verwenden wir das Tool ffmpeg, das – wie der Name vermuten lässt – MPEG-Animationen schreiben kann. Als Filterkette kommt zunächst die gleiche wie in mkedge zum Einsatz, jedoch addiert ein weiterer Schritt das Originalbild glass00.ppm pixelweise dazu (pnmarith). So entsteht ein interessanter Overlay-Effekt. Beim Aufruf von ffmpeg in mkedge (Listing 4) wird das Muster für die Eingabedateien (glass%02d.overlay.ppm) nicht von der Shell expandiert, sondern von ffmpeg selbst.

Listing 4

mkoverlay

#!/bin/sh
for i in glass??.ppm
do
  ppmtopgm $i | pgmedge | pgmnorm > temp.ppm
  pnmarith -add temp.ppm glass00.ppm > ${i%.ppm}.overlay.ppm
done
ffmpeg -an -i glass%02d.overlay.ppm -b 768 g_overlay.mpg

Die gesamte Filter-Vielfalt der Netpbm-Tools ergründen Sie am besten durch Ausprobieren und Lesen der Manpages. Eine Übersicht finden Sie in denen zu pbm, pgm, ppm und pnm. Damit bleibt nur noch die Aufforderung: Experimentieren Sie!

Glossar

Sourceforge

Ein unter http://sourceforge.net/ zu findender Web-Dienst, der viele Open-Source-Projekte beheimatet [1]. Entwicklerforen, Versionsverwaltung, Downloadbereiche und vieles mehr stellt er zur Verfügung.

Povray

Ein frei kopierbares Raytracing-(3D-Grafik)-Programm, das auf vielen Betriebssystemen zu Hause ist – so auch auf Linux. Seine Homepage finden Sie unter http://www.povray.org/; die Heft-CD enthält ein Tutorial in HTML-Form.

Anti-Aliasing

Automatische Kantenglättung bei hohen Kontrasten. So erscheint die Grafik weniger “verpixelt”, es wird eine höhere Auflösung vorgegaukelt.

Standardeingabe

Bei vielen Kommandozeilenprogrammen gibt es die Möglichkeit, den Namen der Eingabedatei wegzulassen. In diesem Fall liest das Programm von der Standardeingabe, die normalerweise mit der Tastatur verbunden ist. Wird der Name der Ausgabedatei weggelassen, geben viele Programme auf der Standardausgabe aus, also sichtbar aufs Terminal.

Standardausgabe

Bei vielen Kommandozeilenprogrammen gibt es die Möglichkeit, den Namen der Eingabedatei wegzulassen. In diesem Fall liest das Programm von der Standardeingabe, die normalerweise mit der Tastatur verbunden ist. Wird der Name der Ausgabedatei weggelassen, geben viele Programme auf der Standardausgabe aus, also sichtbar aufs Terminal.

Pipes

Das Pipezeichen “|” (steht für eine stilisierte Rohrleitung) verbindet die Standardausgabe eines Programms mit der Standardeingabe eines anderen. So lassen sich mehrere Programme zu einem Verarbeitungsschritt zusammen fassen.

Shell-Skripte

Eine Datei mit Shell-Kommandos, die automatisch abgearbeitet werden. Häufig wiederkehrende Arbeitsschritte lassen sich durch Shell-Skripte gut automatisieren.

Infos

[1] Andreas Bauer: “Sourceforge & Co.”, LinuxUser 02/2002, S. 39 ff.

LinuxUser 09/2002 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben