Dize örneği: ASCII sanatı

Flash Player 9 ve üstü, Adobe AIR 1.0 ve üstü

Bu ASCII Art örneği, ActionScript 3.0'da String sınıfıyla çalışılmasının aşağıda örnekleri verilen birçok özelliğini gösterir:

  • String sınıfının split() yöntemi, karakter sınırlı bir dizeden (sekme sınırlı bir metin dosyasındaki görüntü bilgileri) değerleri ayıklamak için kullanılır.

  • split(), bitiştirme ve substring() ile substr() yöntemlerini kullanarak dizenin bir bölümünü ayıklama gibi birçok dize işleme tekniği, görüntü başlıklarındaki her sözcüğün ilk harfini büyük harfli yapmak için kullanılır.

  • getCharAt() yöntemi, bir dizeden tek bir karakter almak için kullanılır (gri tonlamalı bitmap verisine karşılık gelen ASCII karakterini belirlemek için).

  • Dize bitiştirme, bir görüntünün bir defada tek bir karakterle ASCII art temsilini oluşturmak için kullanılır.

ASCII art terimi, bir görüntünün metin temsilini ifade eder, burada, Courier New karakterleri gibi tek boşluklu font karakterlerinin bir ızgarası resmi çizer. Aşağıdaki görüntü, uygulama tarafından oluşturulmuş bir ASCII art örneğini gösterir:

ASCII art - metin karakterleriyle oluşturulan bir görüntü
Grafiğin ASCII art sürümü sağda gösterilir.

Bu örneğin uygulama dosyalarını edinmek için bkz. www.adobe.com/go/learn_programmingAS3samples_flash_tr. ASCIIArt uygulama dosyalarını Samples/AsciiArt klasöründe bulabilirsiniz. Uygulama aşağıdaki dosyaları içerir:

File

Açıklama

AsciiArtApp.mxml

veya

AsciiArtApp.fla

Flash (FLA) veya Flex (MXML) içindeki ana uygulama dosyası

com/example/programmingas3/asciiArt/AsciiArtBuilder.as

Metin dosyasından görüntü meta verisini ayıklama, görüntüleri yükleme ve görüntü-metin dönüştürme işlemini yönetme gibi, uygulamanın ana işlevlerini sağlayan sınıf.

com/example/programmingas3/asciiArt/BitmapToAsciiConverter.as

Görüntü verisinin bir String sürümüne dönüştürülmesi için parseBitmapData() yöntemini sağlayan bir sınıf.

com/example/programmingas3/asciiArt/Image.as

Yüklenen bir bitmap görüntüsünü temsil eden sınıf.

com/example/programmingas3/asciiArt/ImageInfo.as

ASCII art görüntüsünün meta verilerini (örn. başlık, görüntü dosyası URL'si, vb.) temsil eden sınıf.

image/

Uygulama tarafından kullanılan görüntüleri içeren klasör.

txt/ImageData.txt

Uygulama tarafından yüklenecek görüntülerle ilgili bilgileri içeren, sekme sınırlı metin dosyası.

Sekme sınırlı değerleri ayıklama

Bu örnek, yaygın bir uygulama olan, uygulama verilerinin uygulamadan ayrı saklanmasını kullanır; bu şekilde, veri değişirse (örneğin, başka bir görüntü eklenirse veya bir görüntünün başlığı değişirse), SWF dosyasının yeniden oluşturulması gerekmez. Bu durumda, görüntü başlığı, gerçek görüntü dosyasının URL'si ve görüntüyü işlemek için kullanılan bazı değerler gibi görüntü meta verileri, bir metin dosyasında (projedeki txt/ImageData.txt dosyasında) saklanır. Metin dosyasının içerikleri şunlardır:

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

Dosya belirli bir sekme sınırlı biçimi kullanır. Birinci satır, başlık satırıdır. Kalan satırlar, yüklenecek her bitmap için şu verileri içerir:

  • Bitmap'in dosya adı.

  • Bitmap'in görüntü adı.

  • Bitmap'ler için beyaz eşiği ve siyah eşiği değerleri. Bunlar bir pikselin tamamen beyaz veya tamamen siyah olarak değerlendirilmesi için ölçüt olan onaltılık değerlerdir.

Uygulama başlatıldığı anda AsciiArtBuilder sınıfı, AsciiArtBuilder sınıfının parseImageInfo() yönteminden şu kodu kullanarak, görüntülenecek görüntülerin "yığınını" oluşturmak için metin dosyasının içeriklerini yükler ve ayrıştırır:

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); 
    } 
}

Metin dosyasının tüm içerikleri, tek bir String örneği olan _imageInfoLoader.data özelliğinde barındırılır. Parametre olarak yeni satır karakteriyle ("\n") split() yöntemi kullanılarak, String örneği, öğelerinin her biri metin dosyası satırı olan bir Array (lines) öğesine bölünür. Daha sonra kod, satırların her biriyle çalışmak için bir döngü kullanır (gerçek içerik yerine yalnızca başlık içerdiğinden, birinci satır hariç). Döngünün içinde, tek bir satırın içeriklerini, değerler kümesine (imageProperties adındaki Array nesnesi) bölmek için bir kez daha split() yöntemi kullanılır. Bu durumda, her satırdaki karakterler sekme karakterleriyle ayrıldığından, split() yöntemiyle kullanılan parametre, sekme ("\t") karakteridir.

Görüntü başlıklarını normalleştirmek için String yöntemlerini kullanma

Bu uygulamanın tasarım kararlarından biri, görüntü başlıklarının, sözcüklerin her birinin baş harfi büyük olacak şekilde (yaygın olarak baş harfi küçük harfle yazılan birkaç sözcük dışında) standart biçim kullanılarak görüntülenmesidir. Uygulama, metin dosyasının uygun şekilde biçimlendirilmiş başlıklar içerdiğini varsaymak yerine, metin dosyasından ayıklanırken başlıkları biçimlendirir.

Önceki kod listesinde, tek bir görüntünün meta veri değerlerinin ayıklanmasının bir parçası olarak şu kod satırı kullanılır:

        imageInfo.title = normalizeTitle(imageProperties[1]);

Bu kodda, görüntünün başlığı ImageInfo nesnesinde saklanmadan önce normalizeTitle() yöntemiyle metin dosyasından iletilir:

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(" "); 
}

Bu yöntem, başlığı tek tek sözcüklere bölmek için (boşluk karakteriyle ayrılmış şekilde) split() yöntemini kullanır, capitalizeFirstLetter() yöntemi yoluyla sözcüklerin her birini iletir ve sonra sözcükleri tekrar tek bir dize halinde birleştirmek için Array sınıfının join() yöntemini kullanır.

capitalizeFirstLetter() yöntemi, her sözcüğün birinci harfini büyük harf yapma çalışmasını gerçekleştirir.

    /** 
     * 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; 
    }

Türkçe'de, başlıkta şu sözcüklerden biri bulunuyorsa, bu sözcüklerin baş harfi büyük harfli yapılmaz: “ve”, “için”, “ancak”, “fakat”, “veya”, “de” “da” veya “ki” (Bu, kuralların basitleştirilmiş bir sürümüdür.) Bu mantığı çalıştırmak için kod ilk olarak bir switch deyimini kullanarak sözcüğün büyük harfli yapılmaması gereken sözcüklerden biri olup olmadığını kontrol eder. Büyük harfli yapılmaması gereken sözcüklerden biriyse, kod switch deyimini atlar. Diğer yandan, sözcüğün büyük harfli yapılması gerekiyorsa, bu da birkaç adım uygulanarak şu şekilde yapılır:

  1. substr(0, 1) yöntemi kullanılarak sözcüğün birinci harfi ayıklanır, böylece 0 dizinindeki karakterle (0 birinci parametresi tarafından belirtildiği gibi, dizedeki birinci harf) başlayan bir alt dize ayıklanır. Alt dize bir karakter uzunluğundadır (1 ikinci parametresi tarafından belirtildiği gibi).

  2. toUpperCase() yöntemi kullanılarak bu karakter büyük harfli yapılır.

  3. Orijinal sözcüğün kalan karakterleri, substring(1) yöntemi kullanılarak ayıklanır, böylece dizin 1'de başlayan bir alt dize (ikinci harf), dizenin sonuna doğru ayıklanır (substring() yönteminin ikinci parametresinin bırakılmasıyla belirtildiği gibi).

  4. Dize bitiştirmesi kullanılarak, yeni büyük harfli yapılan birinci harf, kalan harflerle birleştirilerek son sözcük oluşturulur: firstLetter + otherLetters.

ASCII art metni oluşturma

BitmapToAsciiConverter sınıfı, bitmap görüntüsünün ASCII metin temsiline dönüştürülmesi işlevselliğini sağlar. Bu işlem, kısmen burada gösterilen parseBitmapData() yöntemi tarafından gerçekleştirilir:

    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;

Bu kod ilk olarak, bitmap görüntüsünün ASCII art sürümünü oluşturmak için kullanılacak result adındaki bir String örneğini tanımlar. Daha sonra, kaynak bitmap görüntüsünün tek tek pikselleri üzerinde döngü gerçekleştirir. Birçok renk işleme tekniğini kullanarak (kısa tutmak amacıyla burada yer verilmemiştir), tek bir pikselin kırmızı, yeşil ve mavi renk değerlerini tek bir gri tonlamalı değere (0 ile 255 arasında bir değer) dönüştürür. Daha sonra kod bu değeri 0-63 ölçeğinde bir değere dönüştürmek için 4'e böler (gösterildiği gibi) ve sonrada bu değer index dizininde saklanır. (Bu uygulama tarafından kullanılan mevcut ASCII karakterlerinin "paleti" 64 değer içerdiğinden, 0-63 ölçeği kullanılır.) Karakterlerin paleti, BitmapToAsciiConverter sınıfında bir String örneği olarak tanımlanır:

// 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 değişkeni, paletteki hangi ASCII karakterinin bitmap görüntüsündeki geçerli piksele karşılık geldiğini tanımladığından, charAt() yöntemi kullanılarak palette String öğesinden o karakter alınır. Daha sonra bitiştirme ataması (+=) operatörü kullanılarak bu karakter result String örneğine eklenir. Ayrıca, her piksel satırının sonunda, result String öğesinin sonuna yeni satır karakteri eklenerek, satır yeni bir "piksel" karakteri satırı oluşturmaya zorlanır.