Este exemplo de Arte ASCII mostra vários recursos para trabalhar com a classe String no ActionScript 3.0, incluindo o seguinte:
-
O método
split()
da classe String é usado para extrair valores de uma string delimitada por caracteres (informações de imagem em um arquivo de texto delimitado por tabulação).
-
Várias técnicas de manipulação de string, incluindo
split()
, concatenação e extração de uma parte da string usando
substring()
e
substr()
, são usadas para colocar a primeira letra de cada palavra em maiúscula nos títulos de imagem.
-
O método
getCharAt()
é usado para obter um único caractere de uma string (para determinar o caractere ASCII correspondente a um valor de bitmap em escala de cinza).
-
A concatenação de string é usada para criar a representação de arte ASCII de uma imagem com um caractere de cada vez.
O termo
arte ASCII
faz referência a representações de texto de uma imagem, na qual uma grade de caracteres de fonte monoespaçada, como caracteres Courier New, plotam a imagem. A imagem a seguir mostra um exemplo de arte ASCII produzida pelo aplicativo:
A versão da arte ASCII do gráfico é mostrada à direita.
Para obter os arquivos de aplicativo desse exemplo, consulte
www.adobe.com/go/learn_programmingAS3samples_flash_br
. Os arquivos do aplicativo ASCIIArt podem ser encontrados na pasta Amostras/AsciiArt. O aplicativo consiste nos seguintes arquivos:
Arquivo
|
Descrição
|
AsciiArtApp.mxml
ou
AsciiArtApp.fla
|
O arquivo principal do aplicativo no Flash (FLA) ou no Flex (MXML)
|
com/example/programmingas3/asciiArt/AsciiArtBuilder.as
|
A classe que fornece a funcionalidade principal do aplicativo, incluindo a extração de metadados da imagem de um arquivo de texto, carregamento de imagens e gerenciamento do processo de conversão de imagem para texto.
|
com/example/programmingas3/asciiArt/BitmapToAsciiConverter.as
|
A classe que fornece o método
parseBitmapData()
para conversão de dados de imagem em uma versão String.
|
com/example/programmingas3/asciiArt/Image.as
|
Uma classe que representa uma imagem de bitmap carregada.
|
com/example/programmingas3/asciiArt/ImageInfo.as
|
Uma classe que representa metadados para uma imagem arte ASCII (como título, URL do arquivo de imagem, etc.)
|
imagem/
|
Uma pasta que contém imagens usadas pelo aplicativo.
|
txt/ImageData.txt
|
O arquivo de texto delimitado por tabulação que contém informações sobre as imagens a serem carregadas pelo aplicativo.
|
Extração de valores delimitados por tabulação
Este exemplo usa a prática comum de armazenar dados do aplicativo separados do próprio aplicativo. Dessa maneira, se os dados forem alterados (por exemplo, se outra imagem for adicionada ou um título da imagem for alterado) não haverá necessidade de recriar o arquivo SWF. Nesse caso, os metadados da imagem, incluindo o título da imagem, a URL do arquivo real da imagem e alguns valores que são usados para manipular a imagem são armazenados em um arquivo de texto (o arquivo txt\ImageData.ttx do projeto). O conteúdo do arquivo de texto é o seguinte:
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
O arquivo usa um formato delimitado por tabulação específico. A primeira linha é uma linha de título. As linhas restantes contêm os seguintes dados para cada bitmap a ser carregado:
-
O nome do arquivo do bitmap.
-
O nome de exibição do bitmap.
-
Os valores de limite de branco e de limite de preto dos bitmaps. Esses são valores hexadecimais acima e abaixo dos quais um pixel deve ser considerado completamente branco ou completamente preto.
Assim que o aplicativo é iniciado, a classe AsciiArtBuilder carrega e analisa o conteúdo do arquivo de texto para criar a “pilha” de imagens que irá exibir usando o seguinte código do método
parseImageInfo()
da 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);
}
}
Todo o conteúdo do arquivo de texto é contido em uma única ocorrência de String, a propriedade
_imageInfoLoader.data
. Usando o método
split()
com o caractere de nova linha (
"\n"
) como um parâmetro, a ocorrência de String é dividida em uma matriz (
linhas
) cujos elementos são as linhas individuais do arquivo de texto. Em seguida, o código usa um loop para trabalhar com cada uma das linhas (exceto a primeira, porque ela contém apenas cabeçalhos em vez do conteúdo real). Dentro do loop, o método
split()
é usado uma vez novamente para dividir o conteúdo da única linha em um conjunto de valores (o objeto Array denominado
imageProperties
). O parâmetro usado com o método
split()
nesse caso é o caractere de tabulação (
"\t"
), porque os valores de cada linha estão delineados por caracteres de tabulação.
Uso de método String para normalizar títulos de imagens
Uma da decisões de design desse aplicativo é que todos os títulos de imagens são exibidos usando um formato padrão, com a primeira letra de cada palavra colocada em maiúscula (exceto por algumas palavras que normalmente não são colocadas em maiúsculas em títulos em inglês). Em vez de assumir que o arquivo de texto contém títulos formatados de maneira apropriada, o aplicativo formata os títulos enquanto eles estão sendo extraídos do arquivo de texto.
Na listagem de código anterior, como parte da extração de valores individuais de metadados da imagem, a seguinte linha de código é usada:
imageInfo.title = normalizeTitle(imageProperties[1]);
Nesse código, o título da imagem do arquivo de texto é passado pelo método
normalizeTitle()
antes de ser armazenado no objeto 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(" ");
}
Esse método usa o método
split()
para dividir o título em palavras individuais (separadas pelo caractere espaço), passa cada palavra pelo método
capitalizeFirstLetter()
e, em seguida, usa o método
join()
da classe Array para combinar as palavras em uma única string novamente.
Como o nome sugere, o método
capitalizeFirstLetter()
realmente faz o trabalho de colocar a primeira letra de cada palavra em maiúscula:
/**
* 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;
}
Em inglês, o caractere inicial de cada palavra em um título
não
será colocado em maiúscula se a palavra for uma das seguintes: “and”, “the”, “in”, “an”, “or”, “at”, “of” ou “a” (essa é uma versão simplificada das regras). Para executar essa lógica, o código primeiro usa uma declaração
switch
para verificar se a palavra é uma das palavras que não devem ser colocadas em letra maiúscula. Nesse caso, o código simplesmente ignora a declaração
switch
. Por outro lado, se a palavra precisar ser colocada em maiúscula, isso será feito em várias etapas, da seguinte maneira:
-
A primeira letra da palavra é extraída usando
substr(0, 1)
que extrai uma substring a partir do caractere no índice 0 (a primeira letra da string, conforme indicado pelo primeiro parâmetro
0
). A substring terá um caractere de comprimento (indicado pelo segundo parâmetro
1
).
-
Esse caractere é colocado em maiúscula usando o método
toUpperCase()
.
-
Os caracteres restantes da palavra original são extraídos usando
substring(1)
que extrai uma substring no índice 1 (a segunda letra) até o final da string (indicado pela omissão do segundo parâmetro do método
substring()
).
-
A palavra final é criada combinando a primeira letra recém colocada em maiúscula com as letras restantes usando concatenação de strings:
firstLetter + otherLetters
.
Geração do texto de arte ASCII
A classe BitmapToAsciiConverter fornece a funcionalidade de converter uma imagem de bitmap em sua representação de texto ASCII. Esse processo é executado pelo método
parseBitmapData()
que é parcialmente mostrado aqui:
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;
Esse código primeiro define uma ocorrência de String denominada
result
que será usada para criar a versão de arte ASCII da imagem de bitmap. Em seguida, ela executa loop pelos pixels individuais da imagem do bitmap de origem. Usando várias técnicas de manipulação de cores (omitidas aqui para resumir), ela converte os valores das cores vermelho, verde e azul de um pixel individual em um valor de escala de cinza único (um número de 0 a 255). Em seguida, o código divide esse valor por 4 (conforme mostrado) para convertê-lo em um valor na escala de 0 a 63 que é armazenado na variável
index
. (A escala de 0 a 63 é usada porque a “paleta” de caracteres ASCII disponíveis usado por esse aplicativo contém 64 valores.) A paleta de caracteres é definida como uma ocorrência de String na 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><+_~-;,. ";
Como a variável
index
define qual caractere ASCII na paleta corresponde ao pixel atual na imagem de bitmap, esse caractere é recuperado da String
palette
usando o método
charAt()
. Em seguida, ele é anexado à ocorrência da String
result
usando o operador de atribuição de concatenação (
+=
). Além disso, no final de cada linha de pixels, um caractere de nova linha é concatenado ao final da String
result
, forçando uma quebra de linha para criar uma nova linha de “pixels” de caracteres.
|
|
|