Voorbeeld van strings: ASCII-afbeeldingen
Flash Player 9 of hoger, Adobe AIR 1.0 of hoger
Dit voorbeeld van een ASCII-tekening laat een aantal kenmerken zien van het werken met de klasse String in ActionScript 3.0, waaronder het volgende:
-
De methode
split()
van de klasse String wordt gebruikt om waarden te extraheren van een door tekens gescheiden tekenreeks (afbeeldingsinformatie in een door tabs gescheiden tekstbestand).
-
U kunt verschillende tekenreeksmanipulatietechnieken, waaronder
split()
, samenvoeging en het extraheren van een deel van de tekenreeks met
substring()
en
substr()
, gebruiken om de eerste letter van ieder woord in de titels van afbeeldingen een hoofdletter te geven.
-
De methode
getCharAt()
wordt gebruikt om één teken uit een tekenreeks op te halen (om vast te stellen welk ASCII-teken overeenkomt met een bitmapwaarde voor grijstinten).
-
Tekenreekssamenvoeging wordt gebruikt om de weergave van een ASCII-tekening met één teken tegelijk op te bouwen.
De term
ASCII-tekening
verwijst naar de tekstweergave van een afbeelding, waarbij de afbeelding in kaart wordt gebracht door een raster van lettertypetekens met vaste tekenbreedte, zoals Courier New-tekens. De volgende afbeelding toont een voorbeeld van een ASCII-tekening die door de toepassing wordt geproduceerd:
De ASCII-tekening van de afbeelding wordt rechts weergegeven.
Zie
www.adobe.com/go/learn_programmingAS3samples_flash_nl
als u de toepassingsbestanden voor dit voorbeeld wilt downloaden. De toepassingsbestanden van ASCIIArt vindt u in de map Samples/ASCIIArt. De toepassing bestaat uit de volgende bestanden:
Bestand
|
Beschrijving
|
AsciiArtApp.mxml
of
AsciiArtApp.fla
|
Het hoofdtoepassingsbestand in Flash (FLA) of Flex (MXML)
|
com/example/programmingas3/asciiArt/AsciiArtBuilder.as
|
De klasse met de hoofdfunctionaliteit van de toepassing, waaronder het extraheren van metagegevens van een afbeelding uit een tekstbestand, het laden van de afbeeldingen en het beheren van het omzettingsproces van afbeelding in tekst.
|
com/example/programmingas3/asciiArt/BitmapToAsciiConverter.as
|
Een klasse die de methode
parseBitmapData()
biedt voor het omzetten van afbeeldingsgegevens in een versie String.
|
com/example/programmingas3/asciiArt/Image.as
|
Een klasse die een geladen bitmapafbeelding weergeeft.
|
com/example/programmingas3/asciiArt/ImageInfo.as
|
Een klasse die metagegevens vertegenwoordigt voor een ASCII-tekening (zoals titel, afbeeldingsbestands-URL, enzovoort).
|
image/
|
Een map met de afbeeldingen die door de toepassing worden gebruikt.
|
txt/ImageData.txt
|
Een door tabs gescheiden tekstbestand met informatie over bestanden die door de toepassing moeten worden geladen.
|
Door tabs gescheiden waarden extraheren
In dit voorbeeld wordt de standaardmethode gebruikt om toepassingsgegevens apart van de toepassing zelf op te slaan. Wanneer gegevens worden gewijzigd (bijvoorbeeld, als een andere afbeelding wordt toegevoegd of de titel van een afbeelding wijzigt), is het niet nodig het SWF-bestand opnieuw te maken. In dit geval worden de metagegevens van de afbeelding, inclusief de titel van de afbeelding, de URL van het daadwerkelijke afbeeldingsbestand en een aantal waarden die worden gebruikt om de afbeelding te manipuleren, opgeslagen in een tekstbestand (het bestand txt/ImageData.txt in het project). De inhoud van het tekstbestand is als volgt:
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
Het bestand gebruikt een specifieke door tabs gescheiden indeling. De eerste regel (rij) is een rij met koptekst. De resterende regels bevatten de volgende gegevens voor iedere te laden bitmap:
-
De bestandsnaam van de bitmap.
-
De weergavenaam van de bitmap.
-
De bitmapdrempelwaarden voor wit en voor zwart. Dit zijn hexadecimale waarden waarboven en waaronder een pixel wordt beschouwd als compleet wit of compleet zwart.
Zodra de toepassing start, wordt de klasse AsciiArtBuilder geladen, waarmee de inhoud van het tekstbestand wordt geparseerd. Zo wordt de 'stapel' met afbeeldingen gemaakt die wordt weergegeven. Dit gebeurt met behulp van de volgende code uit de methode
parseImageInfo()
van de klasse 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);
}
}
De gehele inhoud van het tekstbestand wordt opgenomen in één instantie String, de eigenschap
_imageInfoLoader.data
. Wanneer u de methode
split()
met het teken voor een nieuwe regel (
"\n"
) gebruikt als parameter, wordt de instantie String verdeeld in een Array (
lines
) waarvan de elementen de individuele regels van het tekstbestand zijn. Vervolgens gebruikt de code een lus om met iedere regel te werken (behalve de eerste, omdat die alleen kopteksten bevat en geen daadwerkelijke inhoud). Binnen de lus wordt de methode
split()
nogmaals gebruikt om de inhoud van de ene regel te verdelen in een set waarden (het object Array met de naam
imageProperties
). De parameter die in dit geval bij de methode
split()
wordt gebruikt is het tab-teken (
"\t"
), omdat de waarden in iedere regel door tab-tekens worden afgebakend.
Methoden String gebruiken om afbeeldingstitels te normaliseren
Een van de ontwerpbesluiten voor deze toepassing is dat alle afbeeldingstitels worden weergegeven met een standaardindeling, met de eerste letter van ieder woord als hoofdletter (behalve een paar woorden die normaal gesproken niet met een hoofdletter worden geschreven in titels). In plaats van aan te nemen dat het tekstbestand titels bevat die op de juiste manier zijn opgemaakt, maakt de toepassing de titels op terwijl ze uit het tekstbestand worden geëxtraheerd.
In het vorige codevoorbeeld wordt, als onderdeel van het extraheren van waarden voor metagegevens van afzonderlijke afbeeldingen, de volgende coderegel gebruikt:
imageInfo.title = normalizeTitle(imageProperties[1]);
In deze code wordt de titel van de afbeelding van het tekstbestand aan de methode
normalizeTitle()
doorgegeven voordat deze in het object ImageInfo wordt opgeslagen:
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(" ");
}
Bij deze methode wordt de methode
split()
gebruikt om de titel in afzonderlijke woorden te verdelen (gescheiden door het spatieteken), waarna elk woord wordt doorgegeven aan de methode
capitalizeFirstLetter()
. Vervolgens wordt de methode
join()
van de klasse Array gebruikt om de woorden te combineren, zodat ze weer één tekenreeks vormen.
Met de methode
capitalizeFirstLetter()
wordt dus van de eerste letter van elk woord een hoofdletter gemaakt:
/**
* 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;
}
Voor het Engels geldt dat het eerste teken van woorden in een titel
geen
hoofdletter krijgt als het een van de volgende woorden betreft: 'and', 'the', 'in', 'an', 'or', 'at', 'of' of 'a'. (Dit is een vereenvoudigde versie van de regels.) Voor het uitvoeren van deze logica, gebruikt de code eerst een instructie
switch
om te controleren of het woord een van de woorden is die geen hoofdletter mogen krijgen. Als dat het geval is, springt de code buiten de instructie
switch
. Als het woord wel een hoofdletter moet krijgen, worden de volgende stappen doorlopen:
-
De eerste letter van het woord wordt met
substr(0, 1)
opgehaald, waarbij een subtekenreeks wordt opgehaald dat met een teken op index 0 begint (de eerste letter in de tekenreeks, zoals aangegeven door de eerste parameter
0
). De subtekenreeks is één teken lang (aangeduid door de tweede parameter
1
).
-
Dat teken krijgt een hoofdletter met de methode
toUpperCase()
.
-
De overige tekens van het oorspronkelijke woord worden met
substring(1)
opgehaald, waarbij een subtekenreeks wordt opgehaald dat op index 1 begint (de tweede letter) tot het einde van de tekenreeks (aangeduid door de tweede parameter van de methode
substring()
weg te laten).
-
Het uiteindelijke woord wordt gemaakt door de eerste letter die net een hoofdletter heeft gekregen, te combineren met de overige letters via tekenreekssamenvoeging:
firstLetter + otherLetters
.
ASCII-tekeningtekst genereren
De klasse BitmapToAsciiConverter biedt functionaliteit voor het omzetten van een bitmapafbeelding in de ASCII-tekstrepresentatie ervan. Dit proces wordt uitgevoerd door de methode
parseBitmapData()
en wordt hier gedeeltelijk weergegeven:
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;
Deze code definieert eerst een instantie String met de naam
result
, die wordt gebruikt om de ASCII-versie van de bitmapafbeelding te maken. Vervolgens worden de afzonderlijke pixels van de bronbitmapafbeelding doorlopen. Bij het gebruik van verschillende kleurmanipulatietechnieken (hier weggelaten voor bondigheid), zet de code de rode, groene en blauwe waarden van een afzonderlijke pixel om in één grijsschaalwaarde (een getal van 0 tot 255). Vervolgens wordt de waarde omgezet in een waarde in de 0-63-schaal door de waarde door 4 te delen (zoals in het codevoorbeeld wordt getoond). Deze bewerkte waarde wordt opgeslagen in de variabele
index
. (De 0-63-schaal wordt gebruikt, omdat het 'palet' van beschikbare ASCII-tekens die deze toepassing gebruikt, 64 tekens bevat.) Het palet met tekens wordt gedefinieerd als een instantie String in de klasse 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><+_~-;,. ";
Omdat de variabele
index
bepaalt welk ASCII-teken in het palet overeenkomt met de huidige pixel in de bitmapafbeelding, wordt dat teken opgehaald uit het
palet
String via de methode
charAt()
. Vervolgens wordt het teken toegevoegd aan de String-instantie
result
via de toewijzingsoperator voor samenvoegen (
+=
). Verder wordt aan het eind van elke rij met pixels een teken voor een nieuwe regel samengevoegd met het eind van de String-instantie
result
, zodat tekstomloop wordt afgedwongen voor de regel en een nieuwe regel met 'tekenpixels' wordt gemaakt.
|
|
|
|
|