Oft benötigen ganze Serien digitaler Bilder dieselben Korrekturen, was den Fotografen zu immer gleichen Schritten in Gimp zwingt. Viel bequemer kommt zum Ziel, wer die Retusche automatisiert.
Bevor ich Bilder von meiner digitalen Kamera ins Netz stelle, laufen seit Jahren immer die gleichen Schritte in Gimp ab: Erst verkleinere ich die Bilddatei auf 1000 Pixel Breite, denn die Auflösung meiner Nikon D70 ist schon fast zu hoch fürs Web. Zweitens versuche ich den Kontrast zu verbessern sowie eventuelle Farbstiche zu korrigieren und drittens verbessert die Gimp-Funktion »Sharpen« die Bildschärfe. Üblicherweise stelle ich dabei den Wert »20« ein.
Dabei bietet Gimp – wie schon einmal vor fünf Jahren im Snapshot beschrieben [3] – eine komfortable Skript-Schnittstelle, um diese immer wiederkehrenden Aktionen zu automatisieren und sogar ohne GUI von der Kommandozeile aus ablaufen zu lassen. Allerdings haben die Gimp-Entwickler seither das ganze API durcheinandergewirbelt und nichts funktioniert mehr wie früher. Zum Glück dokumentiert Gimp aber unter dem Menüpunkt »Xtns | Procedure Browser« sämtliche Funktionen vollständig und penibel. Ein dickes Bravo an das Gimp-Team!
Perl-Modul für Gimp
Die Standardschnittstelle ist in der verrückten Professorensprache Scheme geschrieben, zum Glück gibt es aber auch ein Perl-Modul. Zur Installation unter Ubuntu waren ein paar Tricks nötig, die ich weiter unten beschreibe. Danach lässt sich das Skript »picfix« (Listing 1) einfach mit »picfix file.jpg« starten. Es ruft Gimp auf und registriert mit »register()« die Funktion »picfix()« (Zeile 40).
|
Listing 1: |
|---|
001 #!/usr/bin/perl
002 use warnings;
003 use strict;
004
005 use Gimp qw(:auto);
006 use Gimp::Fu;
007 use ColorCast;
008 use Getopt::Std;
009 use Log::Log4perl qw(:easy);
010
011 my $viewer = "eog";
012
013 Log::Log4perl->easy_init($DEBUG);
014
015 getopts("xl:c:a:s:", my %opts);
016
017 $opts{a} ||= "green"; # color adjust
018 $opts{s} ||= "1000"; # size
019 $opts{l} ||= 1; # autolevel
020
021 DEBUG "Starting up";
022
023 my $menu =
024 "<Toolbox>/Xtns/Perl-Fu/Picfix";
025
026 my $file = $ARGV[0];
027 die "No file"
028 unless defined $file;
029
030 register(
031 "perl_fu_picfix", # Name
032 "Fix Colors and More", # Explain
033 "", # Help
034 "", # Author
035 "", # Copyright
036 "", # Date
037 $menu, # Menu
038 "*", # Images accepted
039 [ undef ], # No parameters
040 &picfix # Function
041 );
042
043 exit main();
044
045 ###########################################
046 sub picfix {
047 ###########################################
048
049 my $img = gimp_file_load(
050 RUN_NONINTERACTIVE, $file, $file);
051
052 die "Can't load $file" unless $img;
053
054 my $layer = image_get_active_layer($img);
055
056 scale_image_down($img, $opts{s});
057
058 $layer = $img->get_active_layer();
059 if($opts{l}) {
060 DEBUG "Autolevel [$file]";
061 gimp_levels_stretch($layer);
062 }
063
064 if($opts{c}) {
065 my $colorcast = ColorCast->new(
066 yml_file =>$opts{c},
067 drawable => $layer,
068 );
069 $colorcast->oad();
070 $colorcast->adjust_to($opts{a});
071 }
072
073 DEBUG "Sharpening $file";
074 $img->plug_in_sharpen($layer, 20);
075
076 $file =~ s/./-1./g;
077 $file =~ s/.nef$/.png/g;
078
079 DEBUG "Saving $file";
080 gimp_file_save(
081 RUN_NONINTERACTIVE,
082 $img,
083 $layer,
084 $file,
085 $file);
086
087 system("$viewer $file") if $opts{x};
088 return $img;
089 }
090
091 ###########################################
092 sub scale_image_down {
093 ###########################################
094 my($img, $size) = @_;
095
096 my $w = $img->image_width();
097 my $h = $img->image_height();
098
099 if($w >= $h) {
100 if($w > $size) {
101 $h = int($h * $size/$w);
102 $w = $size;
103 } else {
104 return 1;
105 }
106 } else {
107 if($h > $size) {
108 $w = int($w * $size/$h);
109 $h = $size;
110 } else {
111 return 1;
112 }
113 }
114
115 DEBUG "Resizing to $w x $h";
116 $img->image_scale($w, $h);
117 }
|
Die Gimp-Schnittstelle besteht seltsamerweise darauf, dass auch ein Skript, das nur auf der Kommandozeile läuft, einen vorgegebenen Menü-Eintrag erstellt, also tut »picfix« ihr ab Zeile 37 den Gefallen. In Zeile 43 ruft das Skript die Funktion »main()« auf, die in Gimp verzweigt und erst nach getaner Arbeit zurückkehrt. Das vorangestellte »exit()« stellt sicher, dass sich das Skript mit dem Returncode von »main()« verabschiedet.
Abbildung 1 zeigt das Originalbild, eine Aufnahme von meinem Balkon in San Francisco. Das Abendlicht kam von hinten und leuchtete die Stadt schön aus. Trotzdem waren die Farben im Original nicht ganz richtig. Nach dem Aufruf von »picfix« kam als Ergebnis das Bild in Abbildung 2 heraus. Der Kontrast ist deutlich besser und auch die Farben entsprechen ziemlich genau der Realität.
In der ab Zeile 46 definierten Funktion »picfix()« lädt die Funktion »gimp_file_load()« das Bild unter einem festgelegten Dateinamen. Ein Aufruf von »image_scale()« (Zeile 116) skaliert es auf 1000 Pixel Breite. Die Funktion »gimp_levels_stretch()« (Zeile 61) simuliert dann den »Auto«-Knopf des Gimp-Dialogs »Levels« und maximiert den Kontrast.
Die Methode »plug_in_sharpen()« (Zeile 74) verbessert die Bildschärfe und »gimp_file_save()« (Zeile 80) speichert die Datei unter »file-1.jpg« im ursprünglichen Format. Es ist also egal, ob das Bild als JPG oder PNG vorliegt, die Load/Save-Methoden übergeben intern die Kontrolle an die Routinen fürs passende Bildformat.
Das Laden der Module mit »use Gimp qw(:auto)« und »use Gimp::Fu« importiert alle Gimp-Funktionen in den Namensraum des Skripts. Auch Gimp-Konstanten wie »RUN_NONINTERACTIVE« schleust das »:auto«-Tag zur Freude des Programmierers mit ein.

Abbildung 1: Das Originalbild hat einen leichten Farbstich und der Kontrast ist ebenfalls verbesserungsbedürftig.

Abbildung 2: Das mit dem Perl-Skript »picfix« korrigierte Bild zeigt natürlichere Farben und hat einen höheren Kontrast.
Optionen
Die Bildskalierung ist auf 1000 Pixel voreingestellt (Zeile 18), aber die Kommandozeilenoption »-s« (size) ermöglicht beliebige Werte. Die maximale Größe bezieht sich bei querformatigen Bildern auf die Breite, bei hochformatigen aber auf die Höhe. Die Funktion »scale_image_down()« ab Zeile 92 enthält die dazu notwendige If-else-Logik.
Wer nach getaner Arbeit sein Werk gleich ansehen möchte, kann es über die Option »-x« (für X-Window) mit dem in Zeile 11 eingestellten Viewer (Eye of Gnome, »eog«) ansehen. Und wer auf die Autolevel-Funktion verzichten möchte, die nicht immer zufriedenstellende Ergebnisse liefert, bewerkstelligt dies mit der Option »-l 0« (Zeile 19).
Farbstich
Ist ein Bild zu grün, rot oder blau, stimmt etwas mit der Farbenbalance nicht. Ein weißes Objekt in der fotografierten Szene sollte auch im Foto knallweiß und ohne Farbeinschlag zu sehen sein. Analoges gilt für graue oder pechschwarze Objekte. Wurde der Weißabgleich der Kamera aber nicht justiert, wie es für Profis selbstverständlich ist, sind öfter mal unnatürliche Farbanteile zu sehen. Solche Fehler lassen sich nach einem in [2] beschriebenen Verfahren auch noch hinterher im digitalen Bild korrigieren. Die Möglichkeiten sind beim JPG-Format, das viele preiswerte Kameras per Default verwenden, zwar beschränkt, aber etwas lässt sich meistens doch noch rausholen.
Zunächst ergibt sich das Problem, dass nicht jedes Bild rein weiße, schwarze oder graue Elemente enthält. Es gibt aber im Fotofachhandel genormte Plastikkarten, die der Fotograf einfach ins Bild hält, eine Testaufnahme macht und die Messwerte dann für alle folgenden Aufnahmen der gleichen Szene verwendet. Ändern sich allerdings die Lichtverhältnisse ist eine neue Kontrollaufnahme mit den Karten fällig.
In Abbildung 3 habe ich mit Gimps Color-Picker-Tool den Farbwert einer Stelle der grauen Karte gemessen. Das Ergebnis war: Rot 122, Grün 127 und Blau 123. Wäre die Aufnahme perfekt, müssten alle drei Farbkanäle denselben Wert haben. Ähnliches gilt für die weiße und die schwarze Karte.

Abbildung 3: Ein Satz weißer, grauer und schwarzer Kärtchen erleichtert das Finden der Kontrollpunkte für den Farbabgleich.
Die Datei »colorcast.yml« (Abbildung 4) zeigt die mit Gimp eingefangenen Messwerte im Yaml-Format. Das Skript liest sie aus der Datei ein, deren Namen es in der Kommandozeile findet; »picfix -c colorcast.yml file.jpg«. So kann es anschließend beliebig viele Bilder derselben Szene korrigieren. Dafür muss es alle im Bild verwendeten Farben so transformieren, dass die Farbanteile in den eigentlich farblosen Bildelementen verschwinden. Dazu dient eine Übergangsfunktion, deren Graph sich an den bekannten Messpunkten entlangschlängelt und für alle übrigen Werte Spline-ähnliche Interpolationen bereithält.

Abbildung 4: Die Datei »colorcast.yml« speichert die gemessenen Farbwerte für die weiße, die graue und die schwarze Karte.
In Gimp erlaubt das der »Curves«-Dialog aus dem Menü »Tools | Color Tools«. In seiner Auswahlbox stellt der Retuscheur die zu korrigierende Farbe ein und verbeult dann die anfangs gerade Linie so, dass sie die Kontrollwerte berührt.
Das Verfahren ist recht simpel. Angenommen die graue Karte liefert diese Werte: Rot 122, Grün 127 und Blau 123. Dann besteht die Korrektur einfach darin, sowohl den roten als auch den blauen Kanal auf den Wert 127 für Grün einzustellen. Dadurch ergibt sich das gewünschte farblose Grau. Hierzu öffnet man den roten Kanal im »Curves«-Dialog und zieht die sich geschmeidig anpassende Kurve am Punkt »122/122« (auf der Geraden) zum Punkt »122/127« (Beule).
Gimp zeigt während des Verschiebens links oben die aktuellen Koordinaten an. Im blauen Kanal ist entsprechend der Punkt »123/123« auf den Punkt »123/127« zu verschieben. So entstehen im roten und blauen Kanal leicht verbeulte Kurven wie in Abbildung 5 gezeigt.
Wenn der Fotograf das Verfahren auch für die schwarze und die weiße Karte wiederholt, befinden sich sowohl im roten als auch im blauen Kanal jeweils drei Kontrollpunkte. Das Ganze lässt sich natürlich auch skripten. Listing 2 zeigt, dass der Konstruktor zwei Werte erwartet, »yml_file« (die Yaml-Datei mit den Messwerten) und den Gimp-Layer, (»drawable«).

Abbildung 5: Mit Hilfe des »Curves«-Dialogs lässt sich ein Farbstich korrigieren. Das Beispiel passt dafür die Kurve des roten Kanals mit drei Kontrollpunkten wie im Text beschrieben an.
|
Listing 2: |
|---|
01 ###########################################
02 package ColorCast;
03 # Mike Schilli, 2008 (m@perlmeister.com)
04 ###########################################
05 use strict;
06 use warnings;
07
08 use YAML qw(LoadFile DumpFile);
09 use Gimp qw(:auto);
10 use Log::Log4perl qw(:easy);
11
12 my %channels = (
13 red => HISTOGRAM_RED,
14 blue => HISTOGRAM_BLUE,
15 green => HISTOGRAM_GREEN,
16 );
17
18 ###########################################
19 sub new {
20 ###########################################
21 my($class, %options) = @_;
22
23 my $self = {
24 yml_file => undef,
25 drawable => undef,
26 ctrls => undef,
27 %options,
28 };
29
30 bless $self, $class;
31 }
32
33 ###########################################
34 sub save {
35 ###########################################
36 my($self) = @_;
37
38 DumpFile $self->{yml_file},
39 $self->{ctrls};
40 }
41
42 ###########################################
43 sub load {
44 ###########################################
45 my($self) = @_;
46
47 $self->{ctrls} =
48 LoadFile $self->{yml_file};
49 }
50
51 ###########################################
52 sub adjust_to {
53 ###########################################
54 my($self, $ref_channel) = @_;
55
56 DEBUG "Adjusting to $ref_channel";
57
58 for my $channel (keys %channels) {
59
60 next if $ref_channel eq $channel;
61
62 my $ctrls = $self->{ctrls};
63
64 my @points = (0, 0, 255, 255);
65
66 for my $ctrl (keys %$ctrls) {
67 push @points,
68 $ctrls->{$ctrl}->{$channel},
69 $ctrls->{$ctrl}->{$ref_channel};
70 }
71
72 gimp_curves_spline(
73 $self->{drawable},
74 $channels{ $channel },
75 @points);
76 }
77 }
78
79 1;
|
Die Methode »load()« liest dann die Yaml-Werte ein, die anschließend in einem Hash von Hashes liegen. Ab Zeile 52 erwartet dann »adjust_to()« einen Kanal (etwa »green«), auf den es die Werte der restlichen Kanäle anpasst.
Dies geschieht mit der Gimp-Funktion »gimp_curves_spline()«, die als Parameter den aktiven Layer des zu modifizierenden Bildes, den zu modifizierenden Kanal und eine Reihe von Kontrollpunkten erwartet. Zusätzlich zu den Messpunkten kommen in »adjust_to()« immer auch »(0,0)« und »(255,255)« hinzu, damit die Kurve links unten anfängt und rechts oben aufhört.
Die Option »-c« des Hauptprogramms gibt eine eventuell vorher erstellte Yaml-Datei an und die Option »-a« (adjust) nimmt einen Kanalnamen an, auf den die beiden anderen Kanäle auszurichten sind.
Trickreich installieren
Eigentlich sollte ein einfaches »sudo apt-get install libgimp-perl« die ganze Perl-Gimp-Enchilada installieren, aber leider flippt zumindest Ubuntu 7.10 dabei aus. Synaptic treibt es noch bunter und will gar Gimp und sogar den Ubuntu-Desktop entfernen. Schuld scheint ein kaputtes Gimp-Paket zu sein.
Als Ausweg erlauben es die Kommandos in Listing 3, die »libgimp-perl«-Sourcen herunterzuladen, zu kompilieren, eine Version mit einer um 1 höheren Nummer zu erzeugen und zu installieren. Ganz sauber ist die Lösung nicht, das nächste Gimp-Update wird wahrscheinlich dazwischenfunken. Alternativ käme ein Ubuntu-Ugrade auf 8.04 in Frage, dort gibt es das Problem nicht mehr.

Abbildung 6: Unter dem voreingestellten Loglevel loggt das Skript sehr detailliert mit, was es gerade treibt.
|
Listing 3: Ubuntu |
|---|
01 sudo apt-get install devscripts 02 sudo apt-get source libgimp-perl 03 sudo apt-get build-dep libgimp-perl 04 cd libgimp-perl-2.0.dfsg+2.2pre1.dfsg 05 sudo dch --newversion=2.0.dfsg+2.2pre1.dfsg-3 -- Version Bump 06 sudo dpkg-buildpackage -uc -us 07 cd .. 08 sudo dpkg --install --force-overwrite libgimp-perl_2.0.dfsg+2.2pre1.dfsg-3_i386.deb |
Das Modul »ColorCast.pm« sollte nach der Installation an einem Ort landen, an dem »picfix« es findet, alternativ lässt sich in »picfix« mit »usr lib Verzeichnis;« auf das Installationsverzeichnis von »ColorCast.pm« hinweisen. Die zusätzlich verwendeten Perl-Module Log::Log4perl und Yaml liegen auf dem CPAN und lassen sich mit einer CPAN-Shell oder mit »apt-get install libyaml-perl« und »liblog-log4perl-perl« installieren. Zeile 13 in Listing 1 stellt mit dem Logging-Level »$DEBUG« detailliertes Logging ein (Abbildung 6). Wen diese Geschwätzigkeit nervt, der setzt es auf »$ERROR« hoch.
Manche mögen’s roh
Digitale SLR-Kameras speichern Bilder auf Verlangen auch im Rohformat ab. Allerdings verbraucht dies massiv Speicherplatz und erfordert die Installation des Pakets »gimp-ufraw«. Damit kann Gimp die Daten im ».nef«-Format zwar lesen, aber nicht schreiben. Daher wandelt »picfix« die Datei-Endung in Zeile 77 in ».png« um, worauf Gimp das Ergebnis im PNG-Format speichert. (jcb)
|
Infos |
|---|
|
[1] Listings zu diesem Artikel: [ftp://www.linux-magazin.de/pub/listings/magazin/2008/07/Perl] [2] Carey Bunks, “Grokking the Gimp”: New Riders, 2000 [3] Michael Schilli, “Foto-Labor”: Linux Magazin 09/03, [https://www.linux-magazin.de/Artikel/ausgabe/2003/09/perl/perl.html] [4] Tutorial zu Gimps Perl-Schnittstelle: [http://imagic.weizmann.ac.il/~dov/gimp/perl-tut-2.0/] |
|
Der Autor |
|---|
|
|






