L'esempio ASCII Art illustra varie funzionalità della classe String in ActionScript 3.0, incluso le seguenti:
-
Metodo
split()
della classe String, utilizzato per estrarre valori da una stringa delimitata da caratteri (informazioni di immagine in un file di testo delimitato da tabulazione).
-
Varie tecniche di manipolazione delle stringhe, incluso il metodo
split()
, la concatenazione e l'estrazione di una porzione della stringa mediante i metodi
substring()
e
substr()
, che possono essere utilizzate per rendere maiuscola la prima lettera ogni parola nei titoli delle immagini.
-
Metodo
getCharAt()
, che consente di ottenere un solo carattere da una stringa (per determinare il carattere ASCII corrispondente a un valore bitmap in scala di grigi).
-
La concatenazione di stringhe, utilizzata per creare la rappresentazione ASCII art di un'immagine, un carattere per volta.
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:
La versione ASCII art dell'immagine è riportata sulla destra.
Per ottenere i file dell'applicazione per questo esempio, visitate la pagina
www.adobe.com/go/learn_programmingAS3samples_flash_it
. I file dell'applicazione ASCIIArt si trovano nella cartella Samples/AsciiArt. L'applicazione è composta dai seguenti file:
File
|
Descrizione
|
AsciiArtApp.mxml
o
AsciiArtApp.fla
|
Il file principale dell'applicazione 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.
|
Estrazione di valori delimitati da tabulazione
In questo esempio viene utilizzato il sistema molto diffuso di memorizzare i dati dell'applicazione in una posizione 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:
-
Il nome file della bitmap.
-
Il nome di visualizzazione della bitmap.
-
I valori di soglia del bianco e soglia del nero per le bitmap. Si tratta di valori esadecimali al di sopra o al di sotto dei quali un pixel viene considerato completamente bianco o completamente nero.
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)
{
// 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);
}
}
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:
/**
* 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;
}
In inglese, la lettera iniziale di ciascuna parola di un titolo
non
verrà resa maiuscola se la parola in questione è una delle seguenti: “and”, “the”, “in”, “an”, “or”, “at”, “of” o “a” (questa è una versione semplificata delle regole). 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:
-
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
).
-
Tale carattere viene scritto in maiuscolo utilizzando il metodo
toUpperCase()
.
-
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()
).
-
La 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 = "";
// 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;
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:
// 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><+_~-;,. ";
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.
|
|
|