Strings-Beispiel: ASCII-Grafik
Flash Player 9 und höher, Adobe AIR 1.0 und höher
Im folgenden Beispiel einer ASCII-Grafik werden mehrere Funktionen bei der Verwendung der String-Klasse in ActionScript 3.0 erläutert, einschließlich folgender Funktionen:
-
Mithilfe der
split()
-Methode der String-Klasse werden Werte eines durch Zeichen getrennten Strings extrahiert (Bilddaten in einer durch Tabulatoren getrennten Textdatei).
-
Mehrere Verfahren zur Bearbeitung von Strings, einschließlich
split()
, Verkettung und Extraktion von Teilstrings mit
substring()
und
substr()
werden zur Großschreibung des ersten Buchstabens jedes Wortes in Bildtiteln verwendet.
-
Mithilfe der
getCharAt()
-Methode wird ein einzelnes Zeichen eines Strings abgerufen (um das ASCII-Zeichen zu ermitteln, das einem Graustufen-Bitmapwert entspricht).
-
Mithilfe der Stringverkettung wird Zeichen für Zeichen die ASCII-Grafik-Darstellung eines Bilds erstellt.
Der Begriff
ASCII-Grafik
bezieht sich auf Textdarstellungen eines Bilds, bei dem das Bild durch ein Raster aus Schriftzeichen fester Breite (z. B. Courier New) erstellt wird. Das folgende Bild ist ein Beispiel für eine in der Anwendung erstellte ASCII-Grafik:
Die ASCII-Grafikversion des Bilds ist rechts dargestellt.
Die Anwendungsdateien für dieses Beispiel finden Sie unter
www.adobe.com/go/learn_programmingAS3samples_flash_de
. Die Dateien der Anwendung „ASCIIArt“ befinden sich im Ordner „Samples/AsciiArt“. Die Anwendung umfasst die folgenden Dateien:
Datei
|
Beschreibung
|
AsciiArtApp.mxml
oder
AsciiArtApp.fla
|
Die Hauptanwendungsdatei im Flash-Format (FLA) oder Flex-Format (MXML).
|
com/example/programmingas3/asciiArt/AsciiArtBuilder.as
|
Die Klasse mit den Hauptfunktionen der Anwendung, einschließlich Extrahieren der Bildmetadaten aus einer Textdatei, Laden der Bilder und Verwalten des Vorgangs zum Konvertieren von Bildern in Text.
|
com/example/programmingas3/asciiArt/BitmapToAsciiConverter.as
|
Eine Klasse mit der
parseBitmapData()
-Methode zum Konvertieren von Bilddaten in Strings.
|
com/example/programmingas3/asciiArt/Image.as
|
Eine Klasse, die ein geladenes Bitmapbild darstellt.
|
com/example/programmingas3/asciiArt/ImageInfo.as
|
Eine Klasse mit den Metadaten einer ASCII-Grafik (z. B. Titel oder Bilddatei-URL).
|
image/
|
Ein Ordner mit den in der Anwendung verwendeten Bildern.
|
txt/ImageData.txt
|
Eine durch Tabulatoren getrennte Textdatei mit Informationen zu den Bildern, die von der Anwendung geladen werden.
|
Extrahieren von durch Tabulatoren getrennten Werten
In diesem Beispiel sind entsprechend der gängigen Praxis die Anwendungsdaten getrennt von der Anwendung gespeichert. Auf diese Weise muss die SWF-Datei nicht neu erstellt werden, wenn sich die Daten ändern (z. B. beim Hinzufügen eines weiteren Bilds oder Ändern eines Bildtitels). In diesem Fall sind die Bildmetadaten, darunter der Bildtitel, die URL der Bilddatei und einige Werte zum Bearbeiten des Bilds, in einer Textdatei gespeichert (Datei „txt/ImageData.txt“ im Projekt). Die Textdatei enthält Folgendes:
FILENAME TITLE WHITE_THRESHHOLD BLACK_THRESHHOLD
FruitBasket.jpg Pear, apple, orange, and banana d8 10
Banana.jpg A picture of a banana C8 20
Orange.jpg orange FF 20
Apple.jpg picture of an apple 6E 10
Die Datei weist ein spezifisches, durch Tabulatoren getrenntes Format auf. Die erste Zeile ist eine Kopfzeile. Die restlichen Zeilen enthalten die folgenden Daten für jede zu ladende Bitmap:
-
Den Dateinamen der Bitmap.
-
Den Anzeigenamen der Bitmap.
-
Die Schwellenwerte für die Weiß- und Schwarztöne der Bitmap-Dateien. Dabei handelt es sich um hexadezimale Werte, oberhalb bzw. unterhalb denen ein Pixel als vollständig weiß bzw. vollständig schwarz eingeordnet wird.
Nach dem Starten der Anwendung wird die AsciiArtBuilder-Klasse geladen. Der Inhalt der Textdatei wird mit dem folgenden Code aus der
parseImageInfo()
-Methode der AsciiArtBuilder-Klasse analysiert, um die anzuzeigenden Bilder zu erstellen:
var lines:Array = _imageInfoLoader.data.split("\n");
var numLines:uint = lines.length;
for (var i:uint = 1; i < numLines; i++)
{
var imageInfoRaw:String = lines[i];
...
if (imageInfoRaw.length > 0)
{
// Create a new image info record and add it to the array of image info.
var imageInfo:ImageInfo = new ImageInfo();
// Split the current line into values (separated by tab (\t)
// characters) and extract the individual properties:
var imageProperties:Array = imageInfoRaw.split("\t");
imageInfo.fileName = imageProperties[0];
imageInfo.title = normalizeTitle(imageProperties[1]);
imageInfo.whiteThreshold = parseInt(imageProperties[2], 16);
imageInfo.blackThreshold = parseInt(imageProperties[3], 16);
result.push(imageInfo);
}
}
Der gesamte Inhalt der Textdatei befindet sich in einer einzigen String-Instanz, der Eigenschaft
_imageInfoLoader.data
. Über die
split()
-Methode mit dem Zeilenvorschubzeichen (
\n
) als Parameter wird die String-Instanz in ein Array (
lines
) unterteilt, dessen Elemente die einzelnen Zeilen der Textdatei darstellen. Die einzelnen Zeilen werden in einer Schleife verarbeitet (mit Ausnahme der ersten Zeile, die nur Kopfzeilen und keinen Inhalt enthält). Innerhalb der Schleife wird der Inhalt jeder Zeile wieder mit der
split()
-Methode in eine Wertegruppe unterteilt (das Array-Objekt
imageProperties
). Als Parameter der
split()
-Methode wird in diesem Fall das Tabulatorzeichen (
\t
) verwendet, da die Werte in jeder Zeile durch Tabulatoren getrennt sind.
Verwenden von String-Methoden zum Normalisieren von Bildtiteln
In einer Entwurfsentscheidung für diese Anwendung wurde festgelegt, dass alle Bildtitel im Standardformat angezeigt werden, d. h. Großschreibung des jeweils ersten Buchstabens jedes Worts (mit Ausnahme einiger Wörter, die in englischen Titeln normalerweise nicht in Großbuchstaben geschrieben werden). Die in der Textdatei enthaltenen Titel werden beim Extrahieren aus der Textdatei von der Anwendung formatiert.
Im vorherigen Code wird als Bestandteil der Extraktion einzelner Werte der Bildmetadaten die folgende Codezeile verwendet:
imageInfo.title = normalizeTitle(imageProperties[1]);
Im Code dieser Funktion wird der Bildtitel aus der Textdatei über die
normalizeTitle()
-Methode übergeben und dann im ImageInfo-Objekt gespeichert:
private function normalizeTitle(title:String):String
{
var words:Array = title.split(" ");
var len:uint = words.length;
for (var i:uint; i < len; i++)
{
words[i] = capitalizeFirstLetter(words[i]);
}
return words.join(" ");
}
Mit dieser Methode wird der Titel mithilfe der
split()
-Methode in einzelne (durch Leerzeichen getrennte) Wörter unterteilt. Alle Wörter werden der
capitalizeFirstLetter()
-Methode übergeben und dann über die
join()
-Methode der Array-Klasse wieder zu einem einzelnen String zusammengesetzt.
Wie der Name vermuten lässt, erfolgt die Großschreibung des ersten Buchstabens der einzelnen Wörter über die
capitalizeFirstLetter()
-Methode:
/**
* Capitalizes the first letter of a single word, unless it's one of
* a set of words that are normally not capitalized in English.
*/
private function capitalizeFirstLetter(word:String):String
{
switch (word)
{
case "and":
case "the":
case "in":
case "an":
case "or":
case "at":
case "of":
case "a":
// Don't do anything to these words.
break;
default:
// For any other word, capitalize the first character.
var firstLetter:String = word.substr(0, 1);
firstLetter = firstLetter.toUpperCase();
var otherLetters:String = word.substring(1);
word = firstLetter + otherLetters;
}
return word;
}
Im Englischen wird das erste Zeichen eines Worts in einem Titel
nicht
großgeschrieben, wenn es sich um eines der folgenden Wörter handelt: „and“ „the“, „in“, „an“, „or“, „at“, „of“ oder „a“. (Dies ist eine vereinfachte Version der Regeln.) Im Code wird zuerst mithilfe einer
switch
-Anweisung überprüft, ob es sich bei einem Wort um eines der Wörter handelt, die nicht großgeschrieben werden sollen. Wenn dies der Fall ist, wird die
switch
-Anweisung einfach übersprungen. Wenn ein Wort jedoch großgeschrieben werden muss, erfolgt dies in mehreren Folgeschritten:
-
Der erste Buchstabe des Worts wird mit
substr(0, 1)
extrahiert. Dabei wird ein Teilstring ab dem Zeichen bei Indexposition 0 extrahiert (der erste Buchstabe im String, wie durch den ersten Parameter
0
angegeben). Der Teilstring hat die Länge eines Zeichens (durch den zweiten Parameter
1
angegeben).
-
Dieses Zeichen wird mithilfe der
toUpperCase()
-Methode in einen Großbuchstaben umgewandelt.
-
Die restlichen Zeichen des Worts werden mit
substring(1)
extrahiert. Dabei wird ein Teilstring ab Indexposition 1 (der zweite Buchstabe) bis zum Ende des Strings (keine Angabe des zweiten Parameters für die
substring()
-Methode) extrahiert.
-
Das endgültige Wort wird durch Kombinieren des nun großgeschriebenen ersten Buchstabens mit den restlichen Buchstaben über folgende Stringverkettung erstellt:
firstLetter + otherLetters
Erzeugen des Textes für die ASCII-Grafik
Die BitmapToAsciiConverter-Klasse enthält die Funktionen zum Konvertieren eines Bitmapbilds in die entsprechende ASCII-Textdarstellung. Dieser Vorgang wird über die
parseBitmapData()
-Methode ausgeführt, die im Folgenden teilweise aufgeführt ist:
var result:String = "";
// Loop through the rows of pixels top to bottom:
for (var y:uint = 0; y < _data.height; y += verticalResolution)
{
// Within each row, loop through pixels left to right:
for (var x:uint = 0; x < _data.width; x += horizontalResolution)
{
...
// Convert the gray value in the 0-255 range to a value
// in the 0-64 range (since that's the number of "shades of
// gray" in the set of available characters):
index = Math.floor(grayVal / 4);
result += palette.charAt(index);
}
result += "\n";
}
return result;
Mit diesem Code wird zunächst die String-Instanz
result
definiert, in der die ASCII-Grafikversion des Bitmapbilds erstellt wird. Dann werden die einzelnen Pixel des Quellbitmapbilds durchlaufen. Mit mehreren Verfahren zur Farbbearbeitung (hier aus Platzgründen weggelassen) werden die Rot-, Grün- und Blaufarbwerte eines Pixels in einen Graustufenwert (Zahl von 0 bis 255) konvertiert. Dieser Wert wird dann (wie dargestellt) durch 4 dividiert, sodass er in einen Wert konvertiert wird, der im Bereich zwischen 0 und 63 liegt, und dann in der Variablen
index
gespeichert. (Der Bereich 0-63 wird verwendet, da der Bereich der verfügbaren ASCII-Zeichen in dieser Anwendung 64 Werte umfasst.) Der Bereich der Zeichen ist in der BitmapToAsciiConverter-Klasse als String-Instanz definiert:
// The characters are in order from darkest to lightest, so that their
// position (index) in the string corresponds to a relative color value
// (0 = black).
private static const palette:String = "@#$%&8BMW*mwqpdbkhaoQ0OZXYUJCLtfjzxnuvcr[]{}1()|/?Il!i><+_~-;,. ";
Da durch die
index
-Variable festgelegt ist, welches ASCII-Zeichen im Bereich dem aktuellen Pixel im Bitmapbild entspricht, wird das entsprechende Zeichen mit der
charAt()
-Methode aus dem
palette
-String abgerufen. Es wird dann mit dem Verkettungszuweisungsoperator (
+=
) an die String-Instanz
result
angehängt. Zusätzlich wird am Ende jeder Pixelzeile ein Zeilenvorschubzeichen mit dem Ende des Strings
result
verkettet, sodass die Zeile jeweils umgebrochen und eine neue Zeile mit „Buchstabenpixeln“ erstellt wird.
|
|
|
|
|