Beispiel Angabe

Kürzel:asciishop-A07-PP
Name:AsciiShop, Runde#7
Kette:Asciishop PP
Kategorie:Bildverarbeitung

Mitgelieferte Datei(en): ReplaceOperation.java, Operation.java
Abzugebende Datei(en): OperationException.java, ReplaceOperation.java, MedianOperation.java, Operation.java, LoadOperation.java, ClearOperation.java, AsciiShop.java, AsciiStack.java, AsciiImage.java, AsciiPoint.java
Optional abzugebende Datei(en): TransposeOperation.java, LineOperation.java, FillOperation.java, GrowRegionOperation.java, AsciiStackNode.java
Ausführbar: AsciiShop

Die Klasse AsciiShop ist zu erstellen und soll eine ausführbare Klasse sein und muss daher die public static void main(String[] args) Methode beinhalten. Ihr Programm wird automatisch auf Korrektheit überprüft. Die Überprüfung erfolgt durch die Ausführung der als ausführbar bezeichneten Klasse (AsciiShop).

Kurzbeschreibung:

Das Programm erstellt im ersten Schritt ein leeres Bild, auf dem dann unterschiedliche Operationen ausgeführt werden können. Neben einigen in den Vorrunden implementierten Operationen, gibt es noch einen weiteren Befehl, mit Hilfe dessen das Bild durch einen Medianfilter geglättet wird. Das Rückgängig-Machen einer beliebigen Anzahl von Befehlen ist weiterhin möglich.

Lernziele:

Aufgabenstellung Klassen und Methoden Ein- und Ausgabedaten Bewertung und Kriterien
Hinweise FAQ Fehlerbehandlung Testen

 

Aufgabenstellung:

Um die zwischenzeitlich stark gewachsene Klasse AsciiImage übersichtlicher zu gestalten, sollen alle das Bild veränderten Operationen in eigene Klassen ausgelagert werden. Als algorithmische Aufgabe gilt es in dieser Runde eine neue Operation zu implementieren, die auf dem Bild eine Glättung vornimmt. In einem Bild sind von nun an nur noch bestimmte Zeichen erlaubt. Um ungültige Zeichen und andere Fehlerfälle sinnvoll behandeln zu können, werden ab dieser Runde Exceptions eingesetzt.

Erzeugen des Bildes

Das Erzeugen eines neuen Bildes erfolgt, weitgehend wie in Runde 4 spezifiziert, mit Hilfe des Befehls create, jedoch wird nun neben den beiden Parametern Breite und Höhe des zu erzeugenden Bildes auch der Zeichensatz des Bildes erwartet. Dies ist ein String, der alle im Bild erlaubten Zeichen beinhaltet. Der Zeichensatz gibt außerdem eine Ordnung der Zeichen vor, so ist das erste Zeichen das dunkelste und das letzte das hellste. Jedes Zeichen stellt somit eine Farbe dar. Das hellste Zeichen wird außerdem als Farbe für ein neu erzeugtes Bild sowie beim Löschen des Bildinhaltes bei Eingabe des Befehls clear verwendet.

Charset # W M B R X V Y I t i + = ; : , .
Helligkeitswert 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Beispiel für die Zuordnung Zeichen - Helligkeitswert für das Zeichenset "#WMBRXVYIti+=;:,."

Der create Befehl muss der erste eingegebene Befehl sein. Sie dürfen davon ausgehen, dass sowohl die eingegebene Breite und Höhe als auch der Zeichensatz gültig sind und müssen daher diesen Fehlerfall nicht behandeln. Sollte jedoch einer der Parameter fehlen, geben Sie "INPUT MISMATCH" aus und brechen Sie die Verarbeitung ab.

Das leere Bild kann mit Daten gefüllt werden. Dazu stehen verschiedene Befehle zur Verfügung, darunter der Befehl load. Dieser Befehl (und damit das Einlesen von Bildern von der Standardeingabe) ist für ein gültiges Bild nicht zwingend erforderlich.

Befehle und Operationen am Bild

Die folgenden Befehle sind zulässig, neue und veränderte Befehle sind farblich hervorgehoben, nicht mehr geforderte durchgestrichen:

Alle hier aufgeführten Befehle können in beliebiger Reihenfolge auftreten. So kann zum Beispiel nach create erst print und danach load folgen. Die genannten Befehle clear, filter, load und replace haben entsprechende Klassen, die die Funktionalität implementieren.

Refaktorisierung

Im Verlauf der bisherigen Übungsrunden sind die beiden Klassen AsciiImage und AsciiShop kontinuierlich angewachsen. Mittlerweile befinden sich in beiden Klassen mehr als 200 Zeilen Code, jede neue Funktionalität würde dies weiter vergrößern und somit die Übersichtlichkeit und Wartbarkeit einschränken. Daher gilt es den Code und damit die Struktur des Programms in zwei Schritten umzubauen.

In dieser Runde werden zunächst alle das Bild verändernden Operationen aus der Klasse AsciiImage ausgegliedert. Jede einzelne Operation wird dabei in eine eigene Klasse gekapselt. Der Code in AsciiImage wird so deutlich übersichtlicher und beschränkt sich auf Methoden, die das Bild unmittelbar betreffen, wie beispielsweise das Abfragen von Höhe und Breite oder das Setzen von Pixeln. Nutzen Sie die mitgelieferte und vollständig implementierte ReplaceOperation als Vorlage für ihre eigenen Operationen.

Die Motivation ist für gleichartige Funktionalitäten (nämlich solche Operationen, die das Bild verändern) eine einheitliche Schnittstelle zu schaffen, die festlegt, wie mit der Klasse interagiert werden kann. Beim Verwenden einer Operation reicht das Wissen darüber, was sie tut, sowie die Kenntnis der Schnittstelle, um sie anzuwenden. So soll eine Operation, die Zeichen im Bild ersetzt, auf die gleiche Art und Weise verwendet werden können, wie eine solche, die eine Linie am Bild zeichnet. Die eigentliche konkrete Implementierung der jeweiligen Operation bleibt somit nach außen verborgen und kann auch leicht geändert werden. Die Vereinheitlichung von Schnittstellen wird in Java durch den Einsatz von Interfaces unterstützt. Die Verwendung eines Interfaces ist in dieser Runde jedoch freiwillig. Wenn Sie möchten können Sie das mitgelieferte Interface Operation nutzen.

Implementierung eines Stacks mittels verketteter Liste

In Runde 6 wurde eine Klasse AsciiStack entwickelt, die intern ein Array zur Speicherung der Elemente des Stacks nutzt. Diese Klasse soll nun neu implementiert werden. In der neuen Implementierung soll weder ein Array noch eine vorgefertigte Collectionklasse benutzt werden. Stattdessen soll eine einfach verkettete Liste implementiert werden.


AsciiStack Ein Stack für ASCIIImage-Objekte
Schreiben Sie dafür zusätzlich zur Klasse AsciiStack eine Klasse AsciiStackNode. Ein AsciiStackNode speichert (eine Referenz auf) ein AsciiImage und eine Referenz auf den nächsten (darunter liegenden) Knoten im AsciiStack (siehe Abbildung). Wird dem AsciiStack ein neues Bild hinzugefügt, wird ein neuer Knoten erzeugt und als oberster Knoten eingefügt. Es gibt daher genauso viele Knoten wie Elemente auf dem Stack.

Die Funktionalität der Klasse AsciiStack soll sich gegenüber Runde 6 nicht ändern. Der einzige Unterschied zwischen alter und neuer Schnittstelle ist der, dass der Parameter increment des Konstruktors und die Methode capacity nicht mehr benötigt werden. Objekte der Klasse AsciiStackNode bilden die Struktur des Stacks und sind außerhalb der Klasse AsciiStack nicht sichtbar.

Übungsmöglichkeiten

Sie können zu Übungszwecken, nach dem Muster der anderen Operationen, Klassen für die Befehle grow, line, transpose, sowie fill entsprechend der Spezifikationen der Vorrunden implementieren. Sie können diesen Klassen auch die entsprechenden Befehle zuordnen, dies wird jedoch nicht getestet.

 

Klassen und Methoden:

Die folgende Aufzählung umfasst geforderte Methoden, neue und veränderte Methoden sind farblich hervorgehoben, gegenüber der Vorrunde nicht mehr geforderte durchgestrichen. Sie können nach Bedarf Hilfsmethoden und Methoden für freiwillige Aufgaben (Bonusaufgaben, Übungsaufgaben) hinzufügen. Achten Sie auf die korrekte Datenkapselung. Insbesondere sollen Sie sinnvolle Zugriffsmodifikatoren für Variablen (und Methoden) verwenden.

AsciiShop
Diese Klasse ist ausführbar und beinhaltet daher die main-Methode. Sie verarbeitet die Eingaben, erzeugt das AsciiImage und gibt das Ergebnis aus. Methoden dieser Klasse lesen direkt von System.in ein und geben direkt auf System.out aus.
public static void main(String[] args)
liest die Daten und Befehle ein und gibt das Ergebnis aus.
AsciiImage
Diese Klasse repräsentiert ein ASCII-Bild, es speichert die Zeichen des Bildes und bietet entsprechende Methoden zur Modifikation und zur Abfrage von Eigenschaften, wie beispielsweise Höhe und Breite.
public AsciiImage(int width, int height, String charset)
erzeugt ein ASCII-Bild der spezifizierten Größe und mit dem angegebenen Zeichensatz. Anfangs sind alle Pixel auf den hellsten Wert des Zeichensatzes (also dem letzten Zeichen des Strings) gesetzt. Überprüfen Sie an dieser Stelle ob Breite und Höhe beide größer 0 sind und werfen Sie andernfalls eine IllegalArgumentException. Werfen Sie auch eine IllegalArgumentException, falls das charset ein Zeichen doppelt enthält oder gar keine Zeichen umfasst.
public AsciiImage(int width, int height)
public AsciiImage(AsciiImage img)
ist ein Kopierkonstruktor. Er erzeugt ein neues AsciiImage mit dem gleichen Inhalt, wie im übergebenen Bild.
public void clear()
public void drawLine(int x0, int y0, int x1, int y1, char c)
public String getCharset()
gibt den Zeichensatz des Bildes als String zurück.
public AsciiPoint getCentroid(char c)
public int getHeight()
gibt die Höhe des Bildes (die Anzahl der Zeilen) zurück.
public char getPixel(int x, int y)
gibt das an den übergebenen Koordinaten/Indizes gespeicherte Zeichen zurück. Überprüfen Sie an dieser Stelle, ob die Indizes gültig sind und werfen Sie andernfalls eine IndexOutOfBoundsException.
public char getPixel(AsciiPoint p)
gibt, analog zur Methode public char getPixel(int x, int y), das Zeichen, an der durch p spezifizierten Stelle, zurück. Überprüfen Sie an dieser Stelle, ob die Indizes gültig sind und werfen Sie andernfalls eine IndexOutOfBoundsException.
public ArrayList<AsciiPoint> getPointList(char c)
gibt eine ArrayList aller Pixel eines bestimmten Zeichens zurück. In dieser ArrayList sind Objekte vom Typ AsciiPoint, sollte es keine Punkte mit dem angegebenen Zeichen geben, so soll eine leere Liste zurückgegeben werden. Verwenden Sie diese Methode überall dort, wo sie alle Pixel mit einem bestimmten Zeichen benötigen.
public int getWidth()
gibt die Breite des Bildes (die Länge der Zeilen) zurück.
public void growRegion(char c)
public void replace(char oldChar, char newChar)
public void setPixel(int x, int y, char c)
speichert an den übergebenen Koordinaten/Indizes das übergebene Zeichen. Überprüfen Sie an dieser Stelle, ob die Indizes gültig sind und werfen Sie andernfalls eine IndexOutOfBoundsException. Werfen Sie eine IndexOutOfBoundsException, falls das Zeichen c nicht dem Zeichensatz des Bildes entspricht (sprich nicht im charset enthalten ist).
public void setPixel(AsciiPoint p, char c)
speichert, analog zur Methode public char setPixel(int x, int y, char c), das übergebene Zeichen an der durch p spezifizierten Stelle. Überprüfen Sie an dieser Stelle, ob die Indizes gültig sind und werfen Sie andernfalls eine IndexOutOfBoundsException. Werfen Sie eine IndexOutOfBoundsException, falls das Zeichen c nicht dem Zeichensatz des Bildes entspricht (sprich nicht im charset enthalten ist).
public String toString()
gibt eine lesbare Darstellung des ASCII-Bildes zurück. Die einzelnen Zeilen sollen dabei durch Zeilenumbrüche ‘\n’ getrennt werden.
public void transpose()
public void fill(int x, int y, char c)
AsciiPoint
Diese Klasse repräsentiert einen Punkt, spezifiziert durch zwei ganzzahlige Koordinaten. Diese Klasse ist unveränderlich (immutable), sprich die Koordinaten sollen nachträglich nicht mehr veränderbar sein. Stellen Sie dies durch den Einsatz geeigneter Modifier sicher.
public AsciiPoint(int x, int y)
erzeugt einen Punkt mit den angegebenen Koordinaten.
public int getX()
gibt die x-Koordinate des Punktes zurück.
public int getY()
gibt die y-Koordinate des Punktes zurück.
public String toString()
gibt eine lesbare Darstellung des Punktes in der Form (x,y) zurück.
AsciiStack
Diese Klasse implementiert einen Stack (vgl. Stapelspeicher), der seine Größe dynamisch anpasst. Es kann eine beliebige Anzahl an AsciiImage-Objekten gespeichert werden, wobei der Zugriff immer nur auf das oberste Element möglich ist. Diese Implementierung nutzt intern die Klasse AsciiStackNode um mehrere Bilder in einer Liste zu verketten.
public AsciiStack(int increment)
public AsciiStack()
erzeugt einen leeren Stack.
public int capacity()
public boolean empty()
überprüft, ob zumindest ein Element am Stack liegt.
public AsciiImage pop()
gibt das oberste Element am Stack zurück und entfernt dieses. Liegt kein Element am Stack, so soll null zurückgegeben werden.
public AsciiImage peek()
gibt das oberste Element am Stack zurück ohne es zu entfernen. Liegt nichts am Stack, so soll null zurückgegeben werden.
public void push(AsciiImage img)
legt ein AsciiImage oben auf den Stack.
public int size()
gibt die Anzahl der Elemente im Stack zurück.
AsciiStackNode
Diese Klasse implementiert einen Knoten des Stacks. Beachten Sie untenstehende Hinweise zu dieser Klasse.
public AsciiStackNode(AsciiImage image, AsciiStackNode next)
inizialisiert den Listenknoten.
public AsciiImage getImage()
liefert das vom Knoten referenzierte AsciiImage zurück.
public AsciiStackNode getNext()
liefert eine Referenz auf den nächsten Knoten zurück.
public int size()
liefert die Anzahl der Knoten in der von diesem Knoten referenzierten Restliste plus eins (für diesen Knoten).

Die folgenden Klassen dienen zur Umsetzung bestimmter Bildoperationen. Sie können schon in dieser Runde das mitgelieferte Interface Operation nutzen. Wenn alle hier beschriebenen Klassen dieses Interface implementieren, können Sie so sicher stellen, dass alle Methodensignaturen wie gefordert implementiert wurden. Die execute-Methode soll das übergebene Bild unverändert lassen und als Ergebnis eine Kopie zurückgeben, auf der die Operation ausgeführt wurde.

ClearOperation
Diese Klasse setzt alle Pixel des Bildes auf das hellste Zeichen.
public ClearOperation()
erzeugt eine neue ClearOperation.
public AsciiImage execute(AsciiImage img)
gibt ein neues AsciiImage zurück, das dem übergebenen AsciiImage entspricht, wobei alle Zeichen auf das hellste Zeichen, sprich dem letzten Zeichen im Zeichensatz des Bildes, gesetzt sind.
LoadOperation
Lädt zeilenweise vorliegende Bilddaten in ein AsciiImage.
public LoadOperation(String data)
erzeugt eine neue LoadOperation mit den entsprechenden Bilddaten. Diese Bilddaten liegen als String vor, wobei die Bildzeilen durch Zeilenumbrüche (‘\n’) getrennt sind.
public AsciiImage execute(AsciiImage img) throws OperationException
gibt ein neues AsciiImage zurück, das von Größe und Zeichensatz dem übergebenen AsciiImage entspricht und in das die Daten geladen wurden. Tritt beim Laden ein Fehler auf (zu wenige oder zu viele Daten bzw. ungültige Zeichen), so wird eine OperationException mit einer entsprechenden Fehlermeldung geworfen.
MedianOperation
Diese Klasse glättet ein Bild mit einem 3x3-Medianfilter (vgl. Rangordnungsfilter#Medianfilter).
public MedianOperation()
erzeugt eine neue MedianOperation.
public AsciiImage execute(AsciiImage img)
führt auf einer Kopie des Bildes den Medianfilter aus. Dabei werden immer 3 mal 3 Größe Blöcke des Bildes betrachtet, die Pixel nach ihrem `Helligkeitswert' sortiert und dann der Median (also das in der sortierten Liste in der Mitte stehende Zeichen) als neues Pixel im Mittelpunkt des Blocks gesetzt.
ReplaceOperation
Diese Klasse ersetzt alle Vorkommnisse eines Zeichens in einem Bild durch ein anderes Zeichen. Diese Klasse wird zu Anschauungszwecken vollständig implementiert zur Verfügung gestellt, sie können diese Klasse jedoch auch selber implementieren.
public ReplaceOperation(char oldChar, char newChar)
erzeugt eine neue ReplaceOperation die alle Zeichen oldChar durch newChar ersetzt.
public AsciiImage execute(AsciiImage img) throws OperationException
gibt ein neues AsciiImage zurück, in dem alle Vorkommnisse des Zeichen oldChar durch das Zeichen newChar ersetzt worden sind. Falls das neue Zeichen nicht im Zeichensatz des AsciiImage enthalten ist, soll eine neue OperationException mit entsprechender Fehlermeldung geworfen werden.

Interfaces und Exceptions. Die Verwendung von Interfaces ist in dieser Runde optional.

OperationException extends Exception
Diese Klasse erweitert Exception und wird zum Behandeln aller Fehlerfälle, die beim Ausführen von Operationen auftreten, eingesetzt. Sie dürfen bei Bedarf auch noch weitere Konstruktoren definieren.
public OperationException()
erzeugt eine leere OperationException. Ruft den entsprechenden Super-Konstruktor in der Klasse Exception auf.
public OperationException(String message)
erzeugt eine OperationException mit der entsprechenden Fehlerbeschreibung. Ruft den entsprechenden Super-Konstruktor in der Klasse Exception auf.
Operation
Dieses Interface wird von allen Operationen implementiert (in dieser Runde noch optional) und definiert eine Methode, die zum Ausführen der Operation dient. Dieses Interface wird zur Verfügung gestellt.
public AsciiImage execute(AsciiImage img) throws OperationException
führt die Operation aus und gibt das Ergebnis als neues AsciiImage zurück. Das übergebene AsciiImage wird von der Methode nicht verändert. Mögliche Parameter der Operation müssen im Konstruktor übergeben werden. Sollte beim Ausführen der Operation ein Fehler auftreten, so soll eine OperationException geworfen werden.

 

Hinweise:

Beachten Sie die allgemeinen Hinweise zur Installation und zur Ein-/Ausgabe, sowie zur Abgabe und zur Beurteilung in den FAQ.

Exceptions

Die Klasse AsciiImage wirft ausschließlich spezielle RuntimeExceptions. Diese müssen nicht in der Methodensignatur angegeben werden und sollten auch nur sparsam eingesetzt werden. Sie dienen dazu, fehlerhafte Verwendungen von Methoden aufzuzeigen und sollten daher auch nicht gefangen werden. Überprüfen Sie stattdessen vor dem Verwenden einer Methode, ob die Parameter gültig sind (Indizes liegen im richtigen Bereich, das Zeichen ist erlaubt). Bei den Operationen werden OperationExceptions geworfen. Diese hingegen müssen gefangen werden, um so zum Beispiel den Benutzer auf fehlerhafte Eingaben hinzuweisen.

Refaktorisierung im AsciiShop

Da die Operationen nun in eigene Klassen ausgelagert sind, ist es auch erforderlich im AsciiShop einige Veränderungen vorzunehmen. Lesen Sie nach einem Befehl - wenn erforderlich - zuerst die benötigten Parameter ein und erzeugen Sie dann eine entsprechende Operation, wobei sie die eingelesenen Parameter dem Konstruktor übergeben. Führen Sie dann die Operation aus und behandeln Sie möglicherweise auftretende OperationExceptions.

Load

Die LoadOperation erwartet die gesamten Bilddaten in einem String. Lesen Sie dazu im AsciiShop die Bilddaten zwischen load eof und eof ein und speichern Sie die einzelnen Zeilen durch Zeilenumbrüche getrennt in einen String. Die Validierung der Bilddaten (Zeilenanzahl, Spaltenanzahl, vorkommende Zeichen) erfolgt dann in der LoadOperation. In der Klasse AsciiShop wird nur überprüft, ob der load-Befehl richtig aufgebaut ist, sprich mit dem eof-String endet. Nutzen Sie in der LoadOperation beispielsweise einen Scanner, dem im Konstruktor, der in AsciiShop erzeugte String der eingelesenen Zeilen, übergeben werden kann. So können Sie wie gewohnt zeilenweise die Daten abarbeiten.

Median-Filter

Bei Filteroperation wird für jeden Pixel in Abhängigkeiten von seinen Nachbarpixeln ein neuer Wert bestimmt. Für jeden Pixel des Bildes werden also seine acht Nachbarn und der Pixel selbst betrachtet. Diese neun Zeichen werden entsprechend des Zeichensatzes des Bildes in Helligkeitswerte umgewandelt und anschließend sortiert. Informieren Sie sich über dazu geeignete Hilfsmethoden in der Helper-Klasse java.util.Arrays (vgl. java.util.Arrays). Das Zeichen das dann in der Mitte der sortierten Werte steht (der Median), wird wieder in einen Character umgewandelt und als neuer Helligkeitswert des aktuellen Pixels im Ergebnisbild gesetzt. Ein Randpixel hat weniger als 8 Nachbarn, hier soll angenommen werden, dass die fehlenden drei bis fünf Nachbarn die Hintergrundfarbe haben. Die Zuordnung zwischen Helligkeitswerten und den Zeichen eines Bildes ergeben sich auf Grund der Indizes der Zeichen im charset.


Randbehandlung Randbehandlung (X)
Gelb umrandet ist das Bild (in diesem Fall mit den Abmessungen 6x4). Das aktuelle Pixel, für den der 3x3-Block bestimmt werden soll, ist blau markiert. Dieser, rot strichliert gekennzeichnete Block ragt über den Bildrand hinaus. Für die fünf Blockpunkte in diesem Bereich (farbig hinterlegt) wird explizit die Hintergrundfarbe, in diesem Fall ‘.’, verwendet. Analog ist in allen Fällen zu verfahren, in denen der Block über den Bildrand hinausragt.

Undo-Funktionalität

Nutzen Sie Ihren selber implementierten Stack. Um das Rückgängigmachen von Operationen zu ermöglichen, gehen Sie wie folgt vor: Speichern Sie in einer Variable img (in AsciiShop) immer das aktuelle Bild. Legen Sie, bevor Sie eine Operation, die das Bild verändert, durchführen (das sind insbesondere clear, filter median, load und replace), das Bildes auf den Stack. Entfernen Sie nach Einlesen des Befehls undo jeweils das oberste Element vom Stack, speichern Sie es in die lokale Variable img (in AsciiShop). Geben Sie 'STACK EMPTY` aus, falls keine weiteren Schritte rückgängig gemacht werden können. Beachten Sie, dass der create Befehl nicht rückgängig gemacht werden kann.

Die Klasse AsciiStackNode

Man kann die oben beschriebene Implementierung des Stacks aus dem Blickwinkel einer rekursiven Datenstruktur betrachten, wie im Abschnitt 4.2 des Skriptums beschrieben. Orientieren Sie sich am dort gezeigten Beispiel IntList und IntListNode. Die geforderte Methode int size() zur Bestimmung der Anzahl der Elemente am Stack soll rekursiv implementiert werden. Als Beispiel für eine Methode, die die Elemente der Datenstruktur rekursiv durchmustert, können Sie die Methode boolean contains (int e) in Listing 4.6 im Skriptum auf Seite 244 heranziehen.

Sie können (müssen aber nicht) die Klasse AsciiStackNode auch als innere Klasse von AsciiStack definieren. In diesem Fall können die beiden Methoden getImage() und getNext() auch weggelassen werden, da AsciiStack direkten Zugriff auf die Objektvariablen von AsciiStackNode hat (siehe Skriptum Seite 283), auch wenn diese private deklariert werden.

Wenn Sie Fragen zur Implementierung oder auch zu Java haben, können Sie das Informatik-Forum nutzen. Im Rahmen der wöchentlichen Laborien stehen Tutoren für Fragen zur Verfügung.
Informatik-Forum Laborien

 

Eingabedaten:

Der erste Befehl muss create, gefolgt von Breite und Höhe sowie dem Zeichensatz des Bildes sein. Danach können in beliebiger Reihenfolge beliebige viele der oben definierten Befehle folgen. Beachten Sie jedoch, dass der create Befehl nur einmal (nämlich als erster Befehl) auftreten darf. Sie dürfen davon ausgehen, dass die mittels load eingelesenen Bilddaten keine Leerzeichen enthalten. Sie können weiters davon ausgehen, dass die gesamte Eingabe nicht leer ist.

Ausgabedaten:

Bei jedem Aufruf von print soll das Bild korrekt formatiert und von einer Leerzeile gefolgt, ausgegeben werden. Wird undo eingegeben, so wird, falls der Stack leer ist, "STACK EMPTY" ausgegeben. Im Gegensatz zur vorherigen Runde, wird die Stack Belegung nun nicht mehr ausgegeben.

Fehlerbehandlung:

Geben Sie "INPUT MISMATCH" aus und brechen Sie die weitere Verarbeitung ab, falls einer der folgenden Fehler auftritt:

Geben Sie bei allen Fehlern, die in einer Operationen Klasse ausgelöst werden (also bei denen eine OperationException geworfen wird), "OPERATION FAILED" aus und brechen Sie die weitere Verarbeitung ab. Dies sind insbesondere folgende Fälle:

Geben Sie "UNKNOWN COMMAND" aus und brechen Sie die weitere Verarbeitung ab, falls einer der folgenden Fehler auftritt:

Testen:


In
create 41 20 RPGOEC=o!\(/)_.
load XXX
.........................................
.....!\_________________________/!\......
.....!!.........................!!.\.....
.....!!.........................!!..\....
.....!!.........................!!..!....
.....!!...........PP............!!..!....
.....!!.........................!!..!....
.....!!.........................!!..!....
.....!!.........................!!..!....
.....!!.........................!!../....
.....!!_________________________!!./.....
.....!/_________________________\!/......
........__\_________________/__/!_.......
.......!_______________________!/.)......
.....________________________....(__.....
..../oooo..oooo..oooo..oooo./!..._..)_...
.../ooooooooooooooooooooooo/./..(_)_(_)..
../ooooooooooooooooooooooo/./....(o.o)...
./C=_____________________/_/....==\o/==..
.........................................
XXX
print
Out
.........................................
.....!\_________________________/!\......
.....!!.........................!!.\.....
.....!!.........................!!..\....
.....!!.........................!!..!....
.....!!...........PP............!!..!....
.....!!.........................!!..!....
.....!!.........................!!..!....
.....!!.........................!!..!....
.....!!.........................!!../....
.....!!_________________________!!./.....
.....!/_________________________\!/......
........__\_________________/__/!_.......
.......!_______________________!/.)......
.....________________________....(__.....
..../oooo..oooo..oooo..oooo./!..._..)_...
.../ooooooooooooooooooooooo/./..(_)_(_)..
../ooooooooooooooooooooooo/./....(o.o)...
./C=_____________________/_/....==\o/==..
.........................................
Beschreibung Ein gültiges Bild wird eingelesen.


In
create 30 27 #WMBRXVYIti+=;:,.
load end
============,.V+.;============
===========;.X##..;===========
===========..####..===========
==========,.##M###.:==========
=========;.R##WW##=.;=========
=========..##MWMW##,.=========
========:.I##WWMWW#W.,========
=======;.:##WWWWWW##I.;=======
=======:.W########M##..=======
=======.:############V.;======
=======.####...,.,M###,.======
======,.###:..+++;,B..#.;=====
=====;.#;.#i+YXVVY:#V.#..:====
====:..#..##.RYYIt##...#=.,===
==;..+#;...#######W....##W..:=
:..t###......iVV=....,.+#iM#..
.B#i,#..,,..........,,..#,..#I
V#...#..,,,,,.,,,,:,,,..R#..V#
;#+.i#..,,,,,,,,,.,,,,,.iX.X#,
.i#=MV..,,,,.,,,,,,.,,,..###..
,.t##..,,,,,,,,,,,,,,:,..V##.;
..M#M..,,,,.,.,,,,,,,:,,.=##..
i###M..,...........,,:,,..###.
.####........=II;.....,,.;##R.
,...#....X####MW###B.....Wi..:
==;,##,###;........##i...#;,==
===,.IVi..,;======:..B#B#t.;==
end
filter median
print
Out
.==========,..+...;==========.
===========;,V##;.;===========
===========,;####.:===========
==========;,######:;==========
=========;,R##WW##=:;=========
=========:;##WWWW#W;,=========
========::I##WWWWW#W,;========
=======;::###WWWWW##I,;=======
=======::W###########;;=======
=======::############V,;======
=======:####:.++++M##V,;======
======;;###i:.+++;YBBV.,:=====
=====:,,;##i++YYItYV...;:;====
====;:;;..i#RXXVVVWV...==::===
:==;=++.....RVVVYIt....+Wi=:=.
.;=;i#+......iVV=......+WM,.:.
.:i,t#...,....,,,...,,..iR,.I.
;Vi,i,..,,,,,,,,,,,,,,..ii..VI
;i+=ii..,,,,,,,,,,,,,,,.iXXVV.
.+itVi..,,,,,,,,,,,,,,,..V##;.
.,tMM..,,,,,,,,,,,,,,,,..V##..
.i##M..,,,,,.,,,,,,,,,,,.=##;.
.M##M.........,,,..,,,,,,;##R.
.i##M........=II;.....,..;W#:.
.;;##,...;;..=II;........;i=:.
,=,,,Ii,i;;;=======:i...ti;;;:
.=,,,,i,..................,,;.
Beschreibung Auf ein geladenes Bild wird der Medianfilter angewandt.


In
create 41 20 RPGOEC=o!\(/)_.
load XXX
.........................................
.....!\_________________________/!\......
.....!!.........................!!.\.....
.....!!.........................!!..\....
.....!!.........................!!..!....
.....!!...........PP............!!..!....
.....!!.........................!!..!....
.....!!.........................!!..!....
.....!!.........................!!..!....
.....!!.........................!!../....
.....!!_________________________!!./.....
.....!/_________________________\!/......
........__\_________________/__/!_.......
.......!_______________________!/.)......
.....________________________....(__.....
..../oooo..oooo..oooo..oooo./!..._..)_...
.../ooooooooooooooooooooooo/./..(_)_(_)..
../ooooooooooooooooooooooo/./....(o.o)...
./C=_____________________/_/....==\o/==..
.........................................
XXX
undo
print
undo
Out
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................
.........................................

STACK EMPTY
Beschreibung Das Laden des Bildes wird rückgängig gemacht und das leere Bild ausgegeben. Danach können keine weiteren Schritte rückgängig gemacht werden.


In
create 44 18 #W+,.
replace . t
print
Out
OPERATION FAILED
Beschreibung Die Zeichen können nicht ersetzt werden, da 't' nicht im Zeichensatz des Bildes enthalten ist.


Bemerkung: Diese Beispiele dienen nur zur Verdeutlichung der Spezifikation und müssen nicht korrekt formatiert sein. Die korrekte Formatierung entnehmen Sie bitte dem mitgelieferten Outputfile. Zum Testen Ihrer Lösung können Sie aus den mitgelieferten Eingabedaten wie folgt eine Ausgabedatei erzeugen:
java AsciiShop < asciishop-A07-PP.i1 > asciishop-A07-PP.out1

Das erzeugte File asciishop-A07-PP.out1 können Sie dann mit dem mitgelieferten Outputfile asciishop-A07-PP.o1 vergleichen.