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:

ASCII-Grafik - Ein mit Textzeichen wiedergegebenes Bild
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:

  1. 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).

  2. Dieses Zeichen wird mithilfe der toUpperCase() -Methode in einen Großbuchstaben umgewandelt.

  3. 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.

  4. 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.