例 : ASCII アート

ここでは ASCII アートの例を使って、ActionScript 3.0 の String クラスの操作について次のような機能を示します。

"ASCII アート" という用語はイメージのテキスト表現を指し、イメージは Courier New 文字のような等幅フォント文字のグリッドで描画されます。次のイメージは、アプリケーションが生成した ASCII アートの例を示しています。


サンプルの ASCII アート出力を示すイメージ : 西洋梨のイメージの横に ASCII 文字を使用して作成した西洋梨のイメージがあります。

ASCII アートのグラフィックを右側に示してあります。


このサンプルのアプリケーションファイルを入手するには、www.adobe.com/go/learn_programmingAS3samples_flash_jp を参照してください。ASCIIArt アプリケーションのファイルは、"Samples/AsciiArt" フォルダにあります。アプリケーションは、次のファイルで構成されています。

ファイル

説明

AsciiArtApp.mxml

または

AsciiArtApp.fla

Flash (FLA) または Flex (MXML) のメインアプリケーションファイル

com/example/programmingas3/asciiArt/AsciiArtBuilder.as

テキストファイルからのイメージメタデータの抽出、イメージのロード、イメージからテキストへの変換プロセスの管理など、アプリケーションのメイン機能を提供するクラス。

com/example/programmingas3/asciiArt/BitmapToAsciiConverter.as

イメージデータをストリングに変換するための parseBitmapData() メソッドを提供するクラス。

com/example/programmingas3/asciiArt/Image.as

ロードしたビットマップイメージを表すクラス。

com/example/programmingas3/asciiArt/ImageInfo.as

タイトル、イメージファイル URL など、ASCII アートイメージのメタデータを表すクラス。

image/

アプリケーションが使用するイメージを含むフォルダ。

txt/ImageData.txt

アプリケーションがロードするイメージに関する情報を含む、タブ区切りのテキストファイル。

サブトピック

タブ区切りの値の抽出
ストリングメソッドの使用によるイメージタイトルの正規化
ASCII アートテキストの生成

タブ区切りの値の抽出

この例では、アプリケーションデータをアプリケーション自体とは別に格納する一般的な慣習に従っています。そのようにしておくと、たとえば、別のイメージが追加またはイメージのタイトルが変更されたときなど、データが変更された場合に 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)
    {
        // 新しいイメージ情報レコードを作成し、イメージ情報の配列に追加する
        var imageInfo:ImageInfo = new ImageInfo();

        // 現在の行を (タブ (\t) 文字で区切られた) 値に分割し、
        // 個々のプロパティを抽出する
        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() メソッドは実際に各単語の先頭文字を大文字にする働きがあります。

    /**
     * 以下に示す単語のいずれかでなければ、その先頭文字を大文字にする
     * 除かれるのは、通常は英語で先頭大文字にしない単語である
     */
    private function capitalizeFirstLetter(word:String):String
    {
        switch (word)
        {
            case "and":
            case "the":
            case "in":
            case "an":
            case "or":
            case "at":
            case "of":
            case "a":
                // これらの単語には、何も処理を行わない
                break;
            default:
                // 他の単語では、最初の文字を大文字にする
                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 ステートメントからジャンプします。一方、先頭大文字にする単語の場合は、次のように何ステップかでそれを行います。

  1. substr(0, 1) を使用して、単語の先頭文字を抽出します。この抽出では、第 1 パラメータ 0 が指定するストリングの先頭文字、つまりインデックス 0 の文字から開始するサブストリングを抽出します。サブストリングは、第 2 パラメータ 1 が指定する 1 文字長になります。
  2. toUpperCase() メソッドを使用して、その文字を大文字にします。
  3. substring(1) を使用して、元の単語の残りの文字を抽出します。この抽出では、インデックス 1 (第 2 文字) から開始して、ストリングの末尾 (substring() メソッドの第 2 パラメータの省略が示す) までのサブストリングを抽出します。
  4. firstLetter + otherLetters の文字連結を使用して、新しく大文字にした先頭文字と残りの文字を結合することによって、最終的な単語を作成します。

ASCII アートテキストの生成

BitmapToAsciiConverter クラスは、ビットマップイメージを ASCII テキスト表現に変換する機能を提供します。このプロセスは、次に一部を示してある parseBitmapData() メソッドが実行します。

    var result:String = "";
    
    // ピクセルの行を上から下までループする
    for (var y:uint = 0; y < _data.height; y += verticalResolution)
    {
        // 各行内で、ピクセルを左から右にループする
        for (var x:uint = 0; x < _data.width; x += horizontalResolution)
        {
            ...

            // 範囲 0 ~ 255 の灰色の値を
            // 範囲 0 ~ 64 の値に変換する (使用可能な文字セット内の
            // "灰色の陰影" の数値であるため)
            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 インスタンスとして定義されています。

// 文字は最も濃いほうから最も薄いほうの順に並ぶ
// ストリングの位置 (インデックス) を相対カラー値に対応させるためである
// (0 = 黒)
private static const palette:String = "@#$%&8BMW*mwqpdbkhaoQ0OZXYUJCLtfjzxnuvcr[]{}1()|/?Il!i><+_~-;,. ";

index 変数は、ビットマップイメージの現在のピクセルに対応するパレット内の ASCII 文字を定義するので、この文字は charAt() メソッドを使用して palette ストリングから取得されます。続いて、連結代入演算子 (+=) を使用して、result String インスタンスに追加されます。さらに、各行のピクセルの最後で result String の最後に改行文字を連結して、文字ピクセルの新しい行を作成するために行の折り返しを強制します。


 

このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート

現在のページ: http://livedocs.adobe.com/flash/9.0_jp/main/00000086.html