Hochauflösender Export aus vvvv

Bitte beachten Sie, dass die HTML Version vor allem dazu dient, die indizierbarkeit des Inhals durch Suchmaschinen zu erleichtern. Eine wesentlich lesbarere Version enthält dieses pdf.

 

6| Das Zusammensetzen
.. der Teile

Da der gezeigte Writer (EX9.Texture Grid) eine mehr oder weniger große Anzahl von Einzelbildern generiert, müssen diese zuerst zu einem einzelnen Bild zusammengesetzt werden, bevor das exportierte Bild weiter verarbeitet oder gedruckt werden kann.
Im Folgenden werden 3 Methoden vorgestellt, die dazu eingesetzt werden können:

 

6|1| Manuell

Um die Einzelbilder manuell zu einem einzelnen Bild zusammenzufügen muss zuerst in einem beliebigen Bildbearbeitungsprogramm eine neue Datei angelegt werden, die mindestens genauso groß ist wie die Gesamtgröße der zusammenzusetzenden Einzelbilder. Wurden z.B. 5x5 Bilder mit jeweils 1024x1024 Pixeln exportiert, muss dieses Bild 5120x5120 Pixel groß sein. Bei einer Druckauflösung von 300dpi würde dies einer Ausgabegröße von 43,35 cm entsprechen, wie Abbildung 20 zeigt.

Abb. 20

In dieses leere Bild müssen dann die Einzelbilder der Reihe nach eingefügt werden. Dazu empfiehlt es sich, vorher einen Raster aus Hilfslinien zu definieren (siehe Abbildung 21) um die Einzelbilder leichter anordnen zu können. Sind schließlich alle Teile eingefügt, muss die Datei nur noch gespeichert werden.
Diese manuelle Herangehensweise eignet sich nur, wenn nur sehr wenige Bilder zusammenzufügen sind und auch nur, wenn diese Bilder aus wenigen Teilen bestehen, da der Zeitaufwand beträchtlich ist.

Abb. 21

 

6|2| Automatische Stapelverarbeitung

Anstatt für jedes exportierte Bild alle Einzelteile manuell zusammenzufügen, besteht auch die Möglichkeit mit einem Bildbearbeitungsprogramm, das die Automatisierung von Abläufen unterstützt, eine Stapelverarbeitung (Batch) zu erstellen. So muss ein Handlungsablauf nur einmal vorexerziert werden und kann dann beliebig oft auf andere zusammenzusetzende Bilder angewendet werden. Hier gibt es jedoch beträchtliche Einschränkungen, da die Ausgangssituation bei allen zusammenzusetzenden Bilder exakt gleich sein muss.
Werden z. B. für ein Projekt 5x5 Bilder exportiert und für ein anderes 7x7, muss für die neue Aufgabe eine neue Stapelverarbeitung geschrieben werden. Außerdem ist vor allem bei sehr großen Bildern schon das einmalige manuelle Zusammensetzen eine zeitaufwendige Arbeit.
Die Dateinamen müssen auch immer gleich sein und (zumindest bei Adobe Photoshop) die Einzelteile müssen immer im selben Ordner liegen. Deshalb müssen nach Beendigung der Stapelverarbeitung neue Daten manuell in den Quellordner kopiert und die Stapelverarbeitung neu gestartet werden. So kann immer nur ein Bild ohne Benutzerinteraktion zusammengesetzt werden.

 

6|3| Ein leistungsfähigeres Tool

Um die oben aufgezählten Nachteile einer in einem Bildbearbeitungsprogramm realisierten Stapelverarbeitung zu umgehen, muss ein Programm gefunden werden, das schnell und komfortabel eine beliebige Anzahl von Bildern (in beliebig vielen Ordnern) mit variabler Anzahl von Einzelteilen zusammensetzen kann. Es muss möglich sein, eine Ordnerstruktur einzulesen und alle dort in Einzelteilen gespeicherten Bilder vollautomatisch zu kombinieren, wobei das Programm selbstständig die Ausgabegröße jedes Bildes bestimmen müsste. Bei sehr vielen oder sehr großen Bildern kann es zu längeren Wartezeiten kommen und deshalb muss es möglich sein, das Programm im Hintergrund ablaufen zu lassen, so dass die benutzende Person ungehindert weiterarbeiten kann, während Bilder vom Programm bearbeitet und abgespeichert werden.
Um einen schnellen und unterbrechungsfreien Programmablauf zu ermöglichen sollten sich die Benutzerinteraktionen auf folgende 4 Aktionen beschränken:
1. Pfad zu den Bildern setzen
2. Ausgangsdatentyp einstellen
3. Ablaufpriorität des Programmes einstellen
4. Das Zusammensetzen starten
Da die Reihenfolge der Bilder eindeutig sein muss, wird es gewisse Konventionen für Ordner- und Dateinamen geben müssen. Alle Ordner und Dateien müssen so benannt sein, dass das Programm eindeutig identifizieren kann, welches Ausgangsbild an welche Stelle im zusammengesetzten Bild gehört. Dabei muss es unerheblich sein, welche Pixelgröße die Ausgangsdateien haben und wie viele Dateien im jeweiligen Ordner zu einem großen Bild zusammengesetzt werden sollen.
Ein Beispiel:
In Ordner 001 befinden sich 81 Dateien mit jeweils 1024 x 1024 Pixeln Größe.
In Ordner 002 befinden sich 16 Dateien mit jeweils 512 x 2048 Pixeln Größe.
In Ordner 003 befinden sich 16 Dateien mit jeweils 2048 x 512 Pixeln Größe.
Nach dem vollautomatischen Zusammensetzen sollen die Bilder folgende Größen haben:
Bild 001: 9216 x 9216 Pixel (77 x 77 cm bei 300 dpi)
Bild 002: 2048 x 8192 Pixel (17 x 68 cm bei 300 dpi)
Bild 003: 8192 x 2048 Pixel (68 x 17 cm bei 300 dpi)
Es ist wichtig dass das Gitter, das die Aufteilung des Bildes in Einzelteile bestimmt, immer gleich viele Spalten und Reihen (2 x 2, 3 x 3, 4 x 4, usw.) hat. Ansonsten könnte das Programm nicht selbstständig entscheiden, wie die Einzelteile wieder zu einem korrekten Ausgangsbild zusammengesetzt werden müssen. Die Anzahl von Spalten und Reihen müsste deswegen für jedes Bild explizit angegeben werden.
Darum wird die im Beispiel gezeigte Methode empfohlen um das Seitenverhältnis des zusammenzusetzenden Bildes festzulegen: die Größe der Ausgangsbilder bestimmt das Seitenverhältnis des zusammengesetzten Bildes. Dies ist beim Export mit dem Writer (EX9.Texture Grid) über die Backbuffer Width und Backbuffer Height am Renderer (DX9) einzustellen. Eine weitere Methode um nicht-quadratische Bilder zu exportieren wird im Anhang A|3 kurz erwähnt.
Somit sind die Anforderungen an ein Programm definiert das gut mit dem vorgestellten Exportmodul Writer (EX9.Texture Grid) zusammenarbeiten kann und im folgenden Unterkapitel wir ein geeignetes Programm vorgestellt.

 

6|3|1| Stitcher

Da trotz umfangreicher Recherchen keine Software gefunden werden konnte, welche die oben beschriebenen Funktion bereitstellt, musste dieses Programm neu entwickelt werden. Dank der Hilfe von Alexander Dejaco war es dem Autor dieser Arbeit möglich, dies zu tun. Das Ergebnis ist ein leicht zu bedienendes Programm, das eine beliebige Anzahl von, in Einzelteile zerlegte, Bilder vollautomatisch zusammensetzen und auf einem Datenträger abspeichern kann. Abbildung 22 zeigt die Benutzeroberfläche dieses Programmes.

Abb. 22

Das Programm wurde mit Borland Delphi in der Programmiersprache Pascal geschrieben und es ist etwas über 500 Zeilen lang. In Anhang A|1 und auf dem beiliegenden Datenträger befindet sich der vollständige Quellcode. Es werden keine nicht-standard Module benötigt um das Programm kompilieren zu können. Das Programm ist prozedural geschrieben und beinhaltet 16 Prozeduren und Funktionen, die durch Benutzeraktionen und von anderen Funktionen bzw. Prozeduren aufgerufen werden.
Sobald das Programm geöffnet wird, wird sofort die Prozedur FormActivate ausgeführt, welche die Funktion (loadPathFromReg) aufruft. Es werden lediglich Grundeinstellungen geladen und einige Variablen gesetzt.
Sobald das Programm offen ist, erwartet es eine Aktion. Dazu gibt es folgende Prozeduren:
* about1Click: zeigt ein Informationsdialogfeld an
* btnSetPathClick: Pfad zu den zusammenzusetzenden Bildern
* RadioBmpClick: aktivieren, wenn bmp Bilder zusammengesetzt werden sollen
* RadioJpgClick: aktivieren, wenn jpg Bilder zusammengesetzt werden sollen
* ListPriorityClick: stellt die Prozesspriorität ein
* btnRunClick: startet das Zusammensetzen

Beim Setzen des Pfades muss irgendein Bild in der Ordnerstruktur angewählt werden. Der Stitcher bestimmt dann selbstständig die Anzahl der Ordner und der jeweils darin enthaltenen Bilder. Nach dem Klick auf den „Run“Button (btnRunClick) wird überprüft, ob die Ordner und Dateien den vorgegebenen Namenskonventionen entsprechen, ansonsten wird eine Fehlermeldung ausgegeben.
Es ist wichtig, dass alle Ordner sequenziell nummeriert sind, 3-stellige Namen haben und dass der erste Ordner „001“ heißt. In weiterer Folge heißen die Ordner demnach „002“, „003“, „004“, usw. Für die Dateien gilt das selbe: Datei 1 muss „001.bmp“ bzw. „001.jpg“ heißen. Dabei müssen in allen Ordnern die Dateien das gleiche Dateiformat (bmp oder jpg) haben! Die Anzahl an Dateien kann für jeden Ordner unterschiedlich sein, so lang diese Anzahl quadratisch ist. Ein zusammengesetztes Bild kann demnach aus 4, 9, 16, 25, 36, 49, 64, 81, 100, … Bildern bestehen.
Diese Konventionen sind notwendig, um eine eindeutige Zuordenbarkeit aller Bilder zu gewährleisten. Werden diese eingehalten, bestimmt der Stitcher die Größe des zu erzeugenden Bildes und arbeitet sich dann Bild für Bild durch den ersten Ordner wobei jedes Einzelteil geladen und in einem neuen Bild an der korrekten Position eingefügt wird. Sind alle Bilder eines Ordners im neuen Bild eingefügt, wird dieses abgespeichert und der nächste Ordner in Angriff genommen. Für den nächsten Ordner wird wieder die Ausgabegröße berechnet, die Bilder eingefügt und dann das zusammengesetzte Bild abgespeichert bis alle Ordner abgearbeitet sind. Dabei bekommt jedes zusammengesetzte Bild den selben Namen wie der Quellordner, nur mit der Erweiterung „bmp“.
Der untenstehende Teil des Quellcodes ist die zentrale Schleife im Programm:

ocount := foldercount; // Berechnet die Zahl der Ordner
ProgressBar1.Max := ocount; // Der Fortschrittsbalken
ProgressBar1.Position := 0;
ProgressBar.Position := 0;

for o := 1 to ocount do // Ein Ordner nach dem anderen wird hier abgearbeitet
begin
bmset := false;
LblFolder.Caption := ‘folder ‘ + IntToStr(o) + ‘ of ‘ + IntToStr(ocount);
ProgressBar.Position := 0;
GetCount(o); // Ermittelt die Anzahl der Dateien im Ordner ‘o’
checkcount; // Überprüft die Namenskonventionen
if (error = true) then // Ausgabe einer Fehlermeldung bei falschen Dateinamen
begin
LblDone.Caption := ‘’;
LblTime.Caption := ‘’;
exit;
end;
Calc(o); // Die Positionierung des Teilbildes im grossen Bild
Save(o); // Abspeichern des zusammengesetzten Bildes ‘o’
ProgressBar1.Position := o;
Application.ProcessMessages;
end;


Die Schleife in Pseudocode:
1. Anzahl der Ordner bestimmen
2. Den nächsten Ordner einlesen und die Anzahl und Größe der enthaltenen Bilder bestimmen. All das macht die Funktion GetCount.
3. Die von GetCount ermittelten Daten mit checkcount überprüfen
4. Calc aufrufen, welches das Bild zusammensetzt.
5. Das Bild mit Save speichern.
6. Zurück zu Schritt 2 oder die Schleife beenden wenn alle Bilder zusammengesetzt worden sind.

Die eigentliche Bearbeitung des Bildes erfolgt in Schritt 4 durch die Prozedur Calc. Von dieser werden alle Bilder eines Ordners nacheinander geladen und in das Ausgabebild (SecondBM) eingefügt.
Die Variable i ist die Nummer des aktuellen Bildes und wurzel die Quadratwurzel aus der Gesamtanzahl von Bildern eines Ordners. Befinden sich z.B. 16 Bilder in einem Ordner, ist die Wurzel = 4.

SecondBM.Height := StrToInt(FloatToStr(h * wurzel)); // Höhe des Ausgabebildes
SecondBM.Width := StrToInt(FloatToStr(w * wurzel)); // Breite des Ausgabebildes
x := i mod wurzel; // Berechnung der x Position
if x = 0 then
x := (wurzel - 1) * w
else
x := (x - 1) * w;
y := ((i - 1) div wurzel) * h; // Berechnung der y Position
SecondBM.Canvas.Draw(x, y, JPG);

h und w sind die Pixelgröße (z.B. h = 1024 und w = 512) der zusammenzufügenden Bilder. Die Größe des Ausgabebildes errechnet sich durch Multiplikation der Höhen und Breiten der Quellbilder mit der Anzahl von Bildern in jeder Spalte und Reihe.
Dann wird die x Position berechnet. i ist die Nummer des aktuellen Bildes und x ist der Rest aus der Division von i durch wurzel. Diese Form der Division wird auch Modulo-Funktion genannt. Wenn das Bild Nummer 1 bearbeitet wird, dann wird gerechnet: 1 / 3 = 0 mit 1 Rest. x ist dann also 1.
Bei i = 2 ist x = 2, bei i = 3 ist x = 0 und bei i = 4 ist x = 1.
Dieses Muster setzt sich fort, so dass die Folge 0, 1, 2, 0, 1, 2, ... entsteht.
Wenn wurzel = 4 ist, ergibt sich die Folge 0, 1, 2, 3, 0, 1, ...

Somit ist bekannt, in welche Spalte im Ausgabebild das aktuelle Einzelteil einzusetzen ist. Diese Position muss allerdings in Pixeln angegeben werden, um das Einzelteil an die korrekte Stelle im Ausgangsbild einfügen zu können.
Dazu muss überprüft werden, ob x = 0 ist. Trifft dies nicht zu, wird die Spaltennummer (abzüglich 1), in der sich das Einzelteil befindet, mit der Pixelgröße der Einzelteile multipliziert: x = (x - 1) * w
Das erste bearbeitete Bild (i = 1, x = 1) wird demnach ganz links im Ausgabebild eingefügt:
(1 – 1) * 512 = 0 * 512 = 0
Egal wie groß die Einzelteile sind, durch 0 dividiert wird das erste Bild immer an der x Position 0 stehen.
Für das zweite Bild (i = 2, x = 2) wird w mit 1 multipliziert. Das bedeutet, dass Bild 2 immer genau an jener Stelle eingefügt wird, an der Bild 1 endet.

Diese Methode der Positionsberechnung eignet sich für alle Spalten außer der letzten ganz rechts. Bei x gleich 0 würde der Wert -w zurückgeliefert und das Einzelteil außerhalb der Bildfläche eingefügt.
Deswegen wird dieser spezielle Fall von der if-Abfrage abgefangen und die Berechnung
x = (wurzel - 1) * w durchgeführt.

So kann die x Position für jedes beliebige Einzelteil berechnet werden und deshalb muss nur noch bestimmt werden auf welcher Höhe die Teile eingefügt werden müssen.
Dazu wird eine ganzzahlige Division von i – 1 durch wurzel durchgeführt und diese dann mit der Pixelgröße h multipliziert. Eine ganzzahlige Division liefert zurück, wie oft eine Zahl durch eine andere dividierbar ist. So können z.B. 0, 1 und 2 nicht durch 3 dividiert werden, wenn nur ganze Zahlen benutzt werden, da die Zahl vor den Kommastellen immer kleiner als 1 ist. Wird jede Zahl der Folge 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ganzzahlig durch 3 dividiert, entsteht die Folge 0, 0, 0, 1, 1, 1, 2, 2, 2, 3. Hat ein zusammenzusetzendes Bild also 3 Reihen und Spalten, werden die ersten 3 Bilder ganz oben im Ausgabebild eingesetzt. Die nächsten 3 Bilder dann genau dort, wo die erste Reihe endet.

Nachdem die x und y Positionen eines Einzelteils bestimmt worden sind, kann dieses ins zu exportierende Bild eingefügt werden. Dieser Ablauf wird für alle Dateien im aktuellen Ordner wiederholt! Am Ende wird die Prozedur verlassen und das Programm springt zurück in die Hauptprozedur btnRunClick.
Diese ruft Save auf, das Bild wird gespeichert und dann kehrt die Hauptschleife zu ihrem Ursprung zurück. Der nächste Ordner wird bearbeitet bis alle Bilddateien in der ausgewählten Ordnerstruktur zusammengesetzt worden sind.

Somit kann eine beliebige Anzahl von Bildern vollautomatisch zusammengesetzt werden.
Die gezeigte Lösung „Stitcher“ ist für die Verwendung mit dem Writer (EX9.Texture Grid) konzipiert und nur dadurch ist ein effizienter hochauflösender Export möglich. Wäre das Zusammenfügen der Einzelteile zu kompliziert oder zeitaufwendig, brächte das Exportmodul keinen großen Nutzen.

 

<< zurück || weiter >>

0| Einleitung
1| Auflösung von Bilddateien
2| vvvv als Grafikwerkzeug
3| Zeichenbare Objekte in vvvv
4| Bildexport mit vvvv
5| Export von Bildausschnitten mit vvvv
6| Das Zusammensetzen der Teile
7| Conclusio

A| Anhänge

Zurück zur Diplom-Hauptseite

 
 

(c) by Thomas Hitthaler, ampop.net