ストリングの例:ASCII アートFlash Player 9 以降、Adobe AIR 1.0 以降 ここでは ASCII アートの例を使って、ActionScript 3.0 の String クラスの操作について次のような機能を示します。
ASCII アートという用語はイメージのテキスト表現を指し、イメージは Courier New 文字のような等幅フォント文字のグリッドで描画されます。次のイメージは、アプリケーションが生成した ASCII アートの例を示しています。 ![]() ASCII アートのグラフィックを右側に示してあります。 このサンプルのアプリケーションのファイルを入手するには、www.adobe.com/go/learn_programmingAS3samples_flash_jp を参照してください。 ASCIIArt アプリケーションのファイルは、Samples/AsciiArt フォルダーにあります。 このアプリケーションは次のファイルで構成されています。
タブ区切りの値の抽出この例では、アプリケーションデータをアプリケーション自体とは別に格納する一般的な慣習に従っています。そのようにしておくと、例えば、別のイメージが追加またはイメージのタイトルが変更されたときなど、データが変更された場合に SWF ファイルを再作成する必要がありません。この場合、イメージタイトル、実際のイメージファイルの URL、およびイメージの操作に使用する一部の値を含むイメージメタデータは、テキストファイル(プロジェクトの txt/ImageData.txt ファイル)に格納されています。 実際のテキストファイルの中身は次のようになっています。 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 ファイルは特定のタブ区切り形式を使用します。 最初の行はヘッダー行です。 残りの行は、ロードするビットマップごとに次のデータを含みます。
アプリケーションが起動するとすぐに、AsciiArtBuilder クラスは、AsciiArtBuilder クラスの parseImageInfo() メソッドから次のコードを使用して、表示するイメージの「スタック」を作成するためにテキストファイルの内容をロードして解析します。 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); } } テキストファイルのすべての内容が単一の String インスタンス _imageInfoLoader.data プロパティに含まれます。改行("¥n")をパラメーターとして split() メソッドを使用すると、String インスタンスは、要素がテキストファイルの各行になる Array(lines)に分割されます。次に、ループを使用して各行の操作を行います(実際の内容ではなくヘッダーのみを含む先頭行は除く)。 ループ内で、split() メソッドをもう一度使用して、単一行の内容を値セット(imageProperties という Array オブジェクト)に分割します。各行の値はタブ文字で区切られるため、この場合の split() メソッドで使用するパラメーターはタブ文字("¥t")です。 ストリングメソッドの使用によるイメージタイトルの正規化このアプリケーションの設計に関する決定事項の 1 つは、すべてのイメージタイトルを標準形式で表示し、そのとき各単語の先頭文字を大文字にします(英語タイトルで先頭大文字にしないのが一般的ないくつかの単語は除く)。 適切に整形済みのタイトルがテキストファイルに含まれると見なすのではなく、テキストファイルからの抽出時にタイトルを整形します。 以前のコードリストでは、個々のイメージメタデータ値を抽出する一部として、次のコード行が使用されています。 imageInfo.title = normalizeTitle(imageProperties[1]); このコードでは、テキストファイルからのイメージのタイトルが、ImageInfo オブジェクトに格納される前に normalizeTitle() メソッドを介して渡されます。 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(" "); } このメソッドは split() メソッドを使用して、タイトルを(空白文字で区切られた)個々の単語に分割し、capitalizeFirstLetter() メソッドを介して各単語を渡し、次に Array クラスの join() メソッドを使用して、単語をもう一度 1 つのストリングに結合します。 名前が示すとおり、capitalizeFirstLetter() メソッドは実際に各単語の先頭文字を大文字にする働きがあります。 /** * 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; } 英語では、タイトルの各単語が「and」、「the」、「in」、「an」、「or」、「at」、「of」、または「a」のいずれかである場合、その先頭の文字は大文字にされません。これは簡易版の規則です。このロジックを実行するために、最初に switch ステートメントを使用して、先頭を大文字にしない単語のいずれかであるかどうかを確認します。先頭を大文字にしない単語の場合は、switch ステートメントからジャンプします。一方、先頭を大文字にする単語の場合は、次のように何ステップかでそれを行います。
ASCII アートテキストの生成BitmapToAsciiConverter クラスは、ビットマップイメージを ASCII テキスト表現に変換する機能を提供します。 このプロセスは、次に一部を示してある parseBitmapData() メソッドが実行します。 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; このコードは、ビットマップイメージの ASCII アート版を作成するために使用する result という名前の String インスタンスを最初に定義します。次に、ソースビットマップイメージについて個々のピクセルのループ処理をします。 何とおりかのカラー操作テクニックを使用して(ここでは簡略化のために省略)、個々のピクセルの赤、緑、青のカラー値を単一のグレースケール値(0 から 255 までの数値)に変換します。 続いて例に示してあるように、その値を 4 で割り、0 ~ 63 スケールの値に変換します。値は、変数 index に格納されます。0 ~ 63 スケールを使用するのは、このアプリケーションで使用する利用可能な ASCII 文字の「パレット」に格納される値の数が 64 のためです。文字パレットは、BitmapToAsciiConverter クラスの String インスタンスとして定義されています。 // 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><+_~-;,. "; index 変数は、ビットマップイメージの現在のピクセルに対応するパレット内の ASCII 文字を定義するので、この文字は charAt() メソッドを使用して palette ストリングから取得されます。続いて、連結代入演算子(+=)を使用して、result String インスタンスに追加されます。さらに、各行のピクセルの最後で result String の最後に改行文字を連結して、文字ピクセルの新しい行を作成するために行の折り返しを強制します。 |
![]() |