Esempio: ASCII Art

L'esempio ASCII Art illustra varie funzionalità della classe String in ActionScript 3.0, incluso le seguenti:

Il termine ASCII art si riferisce a rappresentazioni di immagini sotto forma di testo, nelle quali una griglia di caratteri a spaziatura fissa, quali Courier New, va a formare l'immagine. L'illustrazione seguente riporta un esempio di ASCII art prodotto dall'applicazione:


Immagine rappresentante un esempio di ASCII Art: immagine di una pera accanto all'immagine di una pera creata con caratteri ASCII.

La versione ASCII art dell'immagine è riportata sulla destra.


Per ottenere i file dell'applicazione per questo esempio, accedere all'indirizzo www.adobe.com/go/learn_programmingAS3samples_flash_it. I file dell'applicazione ASCIIArt si trovano nella cartella Samples/AsciiArt. L'applicazione è costituita dai seguenti file:

File

Descrizione

AsciiArtApp.mxml

o

AsciiArtApp.fla

Il file dell'applicazione principale in Flash (FLA) o Flex (MXML)

com/example/programmingas3/asciiArt/AsciiArtBuilder.as

Classe che fornisce le funzionalità principali dell'applicazione, inclusa l'estrazione dei metadati dell'immagine da un file di testo, il caricamento delle immagini e la gestione del processo di conversione immagine-testo.

com/example/programmingas3/asciiArt/BitmapToAsciiConverter.as

Classe che fornisce il metodo parseBitmapData() per la conversione dei dati immagini in versione stringa.

com/example/programmingas3/asciiArt/Image.as

Classe che rappresenta un'immagine bitmap caricata.

com/example/programmingas3/asciiArt/ImageInfo.as

Classe che rappresenta metadati di un'immagine ASCII art (quali titolo, URL file di immagine e così via).

image/

Cartella contenente immagini utilizzate dall'applicazione.

txt/ImageData.txt

File di testo delimitato da tabulazione contenente informazioni sulle immagini da caricare mediante l'applicazione.

Sezioni

Estrazione di valori delimitati da tabulazione
Uso dei metodi della classe String per normalizzare i titoli delle immagini
Creazione di testo ASCII art

Estrazione di valori delimitati da tabulazione

In questo esempio viene utilizzato il sistema molto diffuso di memorizzare i dati dell'applicazione in un'ubicazione separata rispetto all'applicazione stessa; in questo modo, se i dati vengono modificati (ad esempio, se viene aggiunta una nuova immagine o se il titolo di un'immagine viene modificato), non sarà più necessario ricreare il file SWF. In questo caso, i metadati dell'immagine, incluso il titolo dell'immagine, l'URL del file dell'immagine vero e proprio e alcuni valori utilizzati per manipolare l'immagine sono memorizzati in un file di testo (il file txt/ImageData.txt del progetto). Il file di testo contiene quanto segue:

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

Il file impiega un formato specifico delimitato da tabulazione. La prima riga è una riga di intestazione. Le restanti righe contengono i seguenti dati per ciascuna bitmap da caricare:

Non appena l'applicazione viene avviata, la classe AsciiArtBuilder carica ed analizza il contenuto del file di testo per creare uno "stack" di immagini da visualizzare mediante il seguente codice del metodo parseImageInfo() della classe AsciiArtBuilder:

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)
    {
        // Crea un nuovo record di informazioni immagine e lo aggiunge all'array delle informazioni immagine.
        var imageInfo:ImageInfo = new ImageInfo();

        // Divide la riga corrente in valori (separati da tabulazione (\t)
        // ) ed estrae singole proprietà:
        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);
    }
}

Tutto il contenuto del file di testo è racchiuso in una sola istanza di String, la proprietà _imageInfoLoader.data. Utilizzando il metodo split() con il carattere nuova riga ("\n") come parametro, l'istanza String viene divisa in un array (lines) i cui elementi sono singole righe del file di testo. Quindi, il codice impiega un ciclo per lavorare con ogni singola riga (tranne la prima, che contiene solo l'intestazione). All'interno del ciclo, il metodo split() viene utilizzato di nuovo per dividere il contenuto della singola riga in una serie di valori (l'oggetto Array chiamato imageProperties). Il parametro utilizzato con il metodo split() in questo caso è il carattere tabulazione ("\t"), in quanto i valori di ogni riga sono delimitati dalla tabulazione.

Uso dei metodi della classe String per normalizzare i titoli delle immagini

Una delle decisioni di progettazione di questa applicazione è che tutti i titoli delle immagini vengano visualizzati in un formato standard, con la prima lettera di ogni parola in maiuscolo (tranne che per alcune parole che generalmente non vengono scritte in maiuscolo nei titoli). Anziché dare per scontato che il file di testo contenga titoli formattati correttamente, l'applicazione formatta i titoli mentre vengono estratti dal file di testo.

Nell'elenco di codice precedente, viene utilizzata la riga seguente per estrarre valori metadati dalle singole immagini:

        imageInfo.title = normalizeTitle(imageProperties[1]);

In questo codice, il titolo dell'immagine viene trasmesso dal file di testo attraverso il metodo normalizeTitle() prima di essere memorizzato nell'oggetto ImageInfo:

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(" ");
}

Questo metodo impiega il metodo split() per dividere il titolo in singole parole (separate dal carattere spazio), passa ogni singola parola attraverso il metodo capitalizeFirstLetter(), quindi usa il metodo join() della classe Array per combinare le parole di nuovo in un'unica stringa.

Come suggerisce il nome, il metodo capitalizeFirstLetter() consente di rendere maiuscola la prima lettera di ogni parola:

    /**
     * Rende maiuscola la prima lettera di una singola parola, eccetto
     * le parole che generalmente non sono maiuscole nei titoli.
     */
    private function capitalizeFirstLetter(word:String):String
    {
        switch (word)
        {
            case "and":
            case "the":
            case "in":
            case "an":
            case "or":
            case "at":
            case "of":
            case "a":
                // Non esegue alcuna operazione su queste parole.
                break;
            default:
                // In tutte le altre parole, scrive in maiuscolo il primo carattere.
                var firstLetter:String = word.substr(0, 1);
                firstLetter = firstLetter.toUpperCase();
                var otherLetters:String = word.substring(1);
                word = firstLetter + otherLetters;
        }
        return word;
    }

Nei titoli, il primo carattere delle seguenti parole non viene scritto in maiuscolo: "e", "il", "in", "un", "o", "a", "di", "per", ecc. (in genere, si tratta di articoli e preposizioni). Per eseguire questa logica, il codice impiega un'istruzione switch per verificare se la parola è tra quelle che non devono essere scritte in maiuscolo. In tal caso, il codice salta semplicemente l'istruzione switch. Se invece la parola deve essere scritta in maiuscolo, l'operazione di trasformazione viene eseguita in varie fasi:

  1. La prima lettera della parola viene estratta mediante la funzione substr(0, 1), che consente di estrarre una sottostringa che inizia con il carattere in posizione di indice 0 (la prima lettera della stringa, come indicato dal primo parametro 0). La sottostringa è lunga un solo carattere (indicato dal secondo parametro 1).
  2. Tale carattere viene scritto in maiuscolo utilizzando il metodo toUpperCase().
  3. I caratteri rimanenti della parola originale vengono estratti mediante la funzione substring(1), che consente di estrarre una sottostringa che inizia nella posizione di indice 1 (seconda lettera) fino alla fine della stringa (indicato dalla non impostazione del secondo parametro del metodo substring()).
  4. L'ultima parola viene creata combinando la prima lettera trasformata in maiuscolo con le restanti lettere mediante concatenazione della stringa: firstLetter + otherLetters.

Creazione di testo ASCII art

La classe BitmapToAsciiConverter fornisce la funzionalità di conversione di un'immagine bitmap nella sua rappresentazione di testo ASCII. Tale procedura viene eseguita dal metodo parseBitmapData(), parzialmente illustrato di seguito:

    var result:String = "";
    
    // Esegue un ciclo tra le righe di pixel dall'inizio alla fine:
    for (var y:uint = 0; y < _data.height; y += verticalResolution)
    {
        // In ogni riga, esegue un ciclo tra i pixel da sinistra a destra:
        for (var x:uint = 0; x < _data.width; x += horizontalResolution)
        {
            ...

            // Converte il valore grigio nell'intervallo compreso tra 0 e 255 in un valore
            // compreso tra 0 e 64 (corrispondente al numero di "sfumature di
            // grigio" nel set di caratteri disponibili):
            index = Math.floor(grayVal / 4);
            result += palette.charAt(index);
        }
        result += "\n";
    }
    return result;

Questo codice definisce in primo luogo un'istanza di String denominata result che verrà utilizzata per creare la versione ASCII art dell'immagine bitmap. Quindi, esegue una funzione ciclica attraverso i singoli pixel dell'immagine bitmap di origine. Mediante una serie di tecniche di manipolazione del colore (qui omesse per ragioni di brevità), i valori di rosso, verde e blu di ogni singolo pixel vengono convertiti in un solo valore in scala di grigi (un numero compreso tra 0 e 255). Il codice divide quindi tale valore per 4 (come illustrato) per convertirlo in un valore della scala che va da 0 a 63, memorizzata nella variabile index. (Viene utilizzata una scala da 0 a 63 perché la "tavolozza" dei caratteri ASCII disponibili per questa applicazione contiene 64 valori.) La tavolozza di caratteri viene definita come un'istanza di String nella classe BitmapToAsciiConverter:

// I caratteri sono ordinati dal più scuro al più chiaro, in modo che
// la loro posizione (index) nella stringa corrisponda al relativo valore di colore
// (0 = nero).
private static const palette:String = "@#$%&8BMW*mwqpdbkhaoQ0OZXYUJCLtfjzxnuvcr[]{}1()|/?Il!i><+_~-;,. ";

Poiché la variabile index definisce quale carattere ASCII nella tavolozza corrisponde al pixel corrente dell'immagine bitmap, tale carattere viene recuperato dalla stringa palette mediante il metodo charAt(). Quindi, esso viene aggiunto all'istanza di String result mediante l'operatore di assegnazione della concatenazione (+=). Inoltre, alla fine di ogni riga di pixel, un carattere nuova riga viene concatenato alla fine della stringa result, per obbligare la riga a tornare a capo e creare una nuova riga di "pixel" di caratteri.


Flash CS3

 

Inviami un messaggio e-mail quando vengono aggiunti dei commenti a questa | Rapporto sui commenti

Pagina corrente: http://livedocs.adobe.com/flash/9.0_it/main/00000086.html