landkarten:kacheltiff

Kacheltiff erstellen

Hier einige Notizen, wie man eine Matrix von Bitmaps (Kacheln) zu einem Bild, einem Kacheltiff (tiled tiff) zusammenfügt.

Obwohl ein Kacheltiff üblicherweise sehr große Bilder enthält (z.B. 10000×10000 Pixel, Speicherbedarf bei 24 Bit: 286 MByte), kann es ressourcenschonend erzeugt werden, da nur die einzelnen Kacheln bearbeitet werden. Das Kacheltiff ist durch seine Dateigröße von 2 GByte beschränkt. Die dabei mögliche Ausdehnung variiert je nach Kompression.

Werkzeug

Ich verwende hier Debian Linux 3.1 (Sarge) mit Bash 2.05b, Perl v5.8.4, gcc 3.3.5 und libtiff 3.7.2-7.

Voraussetzungen

Anforderungen an die Kacheln

Die Kacheln müssen:

  • Alle dieselbe durch 8 teilbare Größe haben. (Üblicherweise 256×256, oder wie hier 512×512 Pixel)
  • Das ganze Bild ohne Löcher, Ränder und Überschneidungen abdecken.

Koordinatensysteme

Pixelkoordinatensystem

Die Positionen der Pixel in einem Bild wird mithilfe eines kartesischen Koordinatensystems festgelegt, dessen Ursprung auf dem linkem oberem Pixel liegt und anhand der Pixelspalten (X-Richtung) bzw. der Pixelzeilen (Y-Richtung) nach rechts bzw. unten gezählt wird.

Kachelkoordinatensystem

Dies ist jedoch für viele Zwecke jedoch unpraktisch, und so verwende ich ich ein weiteres kartesisches Koordinatensystem, welches ggf. in das Pixelkoordinatensystem umgerechnet wird.

Anforderungen an das Kachelkoordinatensystem:

  • Ausgerichtet zum Pixelkoordinatensystem. (X-Achse: Horizontal, Y-Achse: Vertikal)
  • Koordinaten müssen positiv sein. (Bild innerhalb des positiven Quadranten, egal wo dieser liegt.)
  • Länge und Breite einer Kachel umgerechnet in Koordinateneinheiten sollen ganzzahlig sein.

Dateinamen

Die Kacheln sind nach ihrer Position im Kachelkoordinatensystem benannt. Die Position einer Kachel ist die Position ihrer dem Ursprung zugewandten Ecke. (Also jene Ecke, welche die kleinsten Koordinaten der Kachel aufweist.)

Syntax der Dateinamen:

<Verzeichnis>/<Präfix><y>-<x><Postfix>.<Extension>

<Verzeichnis> : Order in dem sich die Dateien befinden. (Voreinstellung: Aktuelles Verzeichnis)
<Präfix>      : Den Koordinaten vorangestellte Zeichenkette.
<y>           : Zeile (Y-Wert) der Kachelposition.
<x>           : Spalte (X-Wert) der Kachelposition.
<Postfix>     : Den Koordinaten nachfolgende Zeichenkette.
<Extention>   : Dateinamenerweiterung.

Beispiel

Ich verwende ein Koordinatensystem dessen Ursprung irgendwo links unten liegt. Die Position der ersten (unteren linken) Kachel ist 5406720-3524096. Die Länge und Breite der Kachel beträgt 256 Einheiten und 512 Pixel. Der Dateiname dieser Kachel ist dann beispielsweise: Bild-5406720-3524096.png.

Verarbeiten von Kacheln auf der Kommandozeile

Um einen Befehl auf mehrere Kacheldateien auszuführen, benutze ich ein kleines selbstgeschriebendes Perlprogramm, das über einen angegebenen Koordinatenbereich iteriert, und alle Dateinamen der Kacheln ausgibt:

$ tile.pl --help
usage: tile.pl -u Ursprung -d Delta -a Anzahl -s Stellen
               -pre Prefix -post Postfix -ext Erweiterung -dir Verzeichnis
               -notest -exist -noexist -younger Datum -older Datum
               -null -line -noprint -exe -noerr -noenv -o Reihenfolge
               [-- Befehl Argumente]
Koordinatensystem: 
  -u Ursprung:    Koordinaten der ersten Kachel
  -d Delta:       Größe einer Kachel in Koordinateneinheiten
  -a Anzahl:      Anzahl der Kacheln
  -s Stellen:     Stellenzahl der Koordinaten
  Alle obigen Angaben in der Form <Zeile>-<Spalte> oder <Zeile>x<Spalte>
  -o Reihenfolge: lo: links oben nach rechts unten, usw ...
Dateinamen: 
  -pre Prefix:      Anfang des Dateinamens
  -post Postfix:    Ende des Dateinamens
  -ext Erweiterung: Dateinamenerweiterung
  -dir Verzeichnis: Verzeichnis mit den Kacheldateien
Dateitests/-filter:
  -notest:        Kein Abbruch wenn Dateien nicht existieren.
  -exist:         Dateien ausschließen, die nicht existieren.
                  (impliziert: -notest)
  -noexist:       Dateien ausschließen, die existieren. (impliziert: -notest)
  -younger Datum: Dateien ausschließen, die älter als Datum sind.
  -older Datum:   Dateien ausschließen, die jünger als Datum sind.
Ausgabe:
  -null:          Verwendet Null-Zeichen als Terminator.
  -line:          Gibt alle Dateien in einer Zeile aus.
  -noprint:       Unterdrückt die Ausgabe.
  -exe:           Führt die Ausgabe als Befehl/Programm aus.
  -noerr:         Ignoriert den Rückgabewert des Befehls
  -noenv:         Ignoriert die Umgebungsvariable TILEOPT
Argumente:
  Alle angegebenen Argumente werden direkt in die Ausgabe übernommen mit
  Ausnahme folgender Zeichenketten:
  {} oder {n}: Dateiname ohne Erweiterung (Defaultargument)
  {f}:         Dateiname mit Erweiterung
  {d}:         Verzeichnis
  {e}:         Dateinamenerweiterung
  {p}:         Vollständiger Pfadname der Datei
  Wird keine dieser Zeichenketten angegeben, wird das Defaultargument an die
  Ausgabe angehängt

Alle Parameter und Argumente können inkl. Shell-Expansion in der Umgebungs-
variable TILEOPT vorgegeben werden. Das Argument '~~' gibt die Lage der Kommandozeile an.

Der folgende Befehl kopiert zwei Zeilen mit je 5 Kacheln aus dem übergeordneten Verzeichnis in das aktuelle Verzeichnis in dem für jede Kachel der Kopierbefehl angewandt wird:

tile.pl -exe -dir .. -u 5406720-3524096 -a 2x5 cp {p} .

Parameter und Argumente können auch über die Umgebungsvariable TILEOPT vorgegeben werden. Sinnvoll ist dies beispielweise für die Festlegung des Koordinatensystems:

export TILEOPT='-u $((5406720+86*256))-$((3524096+96*256)) -a 86x96'

Korrumpierte Kacheln löschen

Der folgende Befehl prüft alle Dateien, die nach 15:00 modifiziert wurden, und löscht jene, die keine Bilder im PNG-Format mit einer Höhe und Breite von 554×512 Pixel sind:

tile.pl -exe -noprint -exist -younger 15:00 '[[ `identify -format "%m-%h-%w" {f}` == "PNG-554-512" ]] || rm {f}'

Kacheln konvertieren und zuschneiden

Eine Kachel ins Tiff-Format konvertieren

Der folgende Imagemagick-Befehl erstellt eine Tiffdatei Bild-5406720-3524096.tiff mit dem Inhalt der Datei Bild-5406720-3524096.png:

convert -density 72x72  -units PixelsPerInch Bild-5406720-3524096.png Bild-5406720-3524096.tiff

Die Angabe der Parameter units und density ist notwendig um eine korrekte Tiffdatei zu erstellen.

Eine Kachel zuschneiden

Der folgende Imagemagick-Befehl beschneidet das Bild in der Datei Bild-5406720-3524096.tiff auf 512×512 Pixel, beginnend von der oberen linken Ecke (Pixelposition: +0+0):

mogrify -crop 512x512+0+0 Bild-5406720-3524096.tiff

Alle Kacheln zuschneiden und ins Tiff-Format konvertieren

Die folgende Befehlzeile konvertiert und schneidet die im Verzeichnis ../versuch7 befindlichen PNG-Dateien in TIFF-Dateien des aktuellen Verzeichnisses:

tile.pl -exe -dir ../versuch7 -ext png -- convert -crop 512x512+0+0 -density 72x72 -units PixelsPerInch {p} {n}.tiff

Kacheln mit Imagemagick zusammensetzen

Hier werden die einzelnen Kacheln im Speicher des Rechners zusammengesetzt. Deshalb eignet sich die Methode nur für kleine Bilder. Der folgende Befehl setzt 2×5 Kacheln zu einem Bild zusammen:

tile.pl -o lu -exe -line -a 2x5 -- montage +frame +shadow +label -geometry 100% -tile 5x2 {f} bild.png

Kacheltiff erzeugen

Ich habe ein Programm in der Programmiersprache C geschrieben, das die nun im Tiff-Format vorliegenden Kacheln nacheinander liest und in ein Kacheltiff abspeichert. Da sich hier nur immer eine Kachel im Speicher befindet, funktioniert dies schnell und ressourcenschonend.

Vorbereitungen

Um das Programm übersetzen zu können, benötigt man die libtiff-Bibliothek und den Übersetzer gcc. Diese Software muss zuerst installiert werden. Bei Debian-Linux genügt dafür ein APT-Aufruf. Danach kann man mit

gcc -l tiff tiffread.c -o tiletiff

den Quellcode in der tiffread.c in das ausführbare Programm tiletiff übersetzen.

Ausführung

Der folgende Befehl setzt das Kacheltiff in der Datei kacheltiff.tif aus 86*96=8256 Kacheln mit jeweils 512×512 Pixel zusammen. Die Dateinamen der einzelnen Kacheln werden vom oben besprochenen Perlprogamm tile.pl erzeugt und auf der Standardeingabe übergeben:

tile.pl -o lu -ext tiff {p}|tiletiff -a 86x96 -p 512x512 -o kacheltiff.tif

Die Laufzeit dieses Befehls beträgt auf meinen Pentum 4 1,8 GHz 12 Minuten, also über 10 Kacheln/Sekunde. Die erzeugte Datei ist ca. 1,1 GByte groß. Das Ausgangsmaterial (PNG-Kacheln) hat 2,3 GByte.

Output

Es wird ein Kacheltiff im RGB-Farbschema mit 4 Samples/Pixel und JPEG-Komprimierung erzeugt. Mit diesem Format habe ich bisher die besten Erfahrungen in TTQV gemacht.

Download

Wer sich die Programme näher anschauen will, kann Sie hier herunterladen: tiletiff.zip

landkarten/kacheltiff.txt · Zuletzt geändert: 2014/09/13 19:12 (Externe Bearbeitung)

Seiten-Werkzeuge