IconizedClass – Update

In der aktuellen Version habe ich noch einiges an Performance raus holen können indem ich eine andere Vorrangeheweise gewählt habe. Und zwar lese ich nicht mehr jeden Pixel einzeln und speichere diesen umgewandelt in einem String, sondern verwende die Klasse PNGEncoder um das Bild in ein ByteArray umzuwandeln. Im nächsten Schritt wandle ich das ByteArray dann mit der Klasse Base64Encoder in ein Base64 kodierter String um, diesen ich wiederum speichere.


Die Anwendung wurde im ersten Artikel aktualisiert:
http://weltchefflasher.de/blog/2010/03/25/iconized_class/

Hier ein paar Einblicke wie ich die Klasse generiere:

Die zu erzeugte Klasse an sich steht in einem Template und wird eingebettet durch:

[Embed(source="../embed/template-default.as", mimeType="application/octet-stream")]
public static const template_default : Class;

Anschließend wird das Template als String abgelegt:

private function setDefaultTemplate() : void
{
   var file : ByteArray = new template_default();
   
   _template = file.readUTFBytes(file.length);
   _template = String(_template).split("\r").join("");
}

Das aktuelle Template sieht folgend aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package
{
   import mx.utils.Base64Decoder;

   import flash.display.Bitmap;
   import flash.display.BitmapData;
   import flash.display.Loader;
   import flash.display.LoaderInfo;
   import flash.events.Event;
   import flash.utils.ByteArray;

   public class MyIconClass extends Bitmap
   {
      private static var bitmapDataCache : BitmapData;

      public function MyIconClass()
      {
         if(!bitmapDataCache) {
            generateBitmapData();
         } else {
            this.bitmapData = bitmapDataCache;
         }
      }

      public static function preGenerate() : void
      {
         new MyIconClass();
      }

      private function generateBitmapData() : void
      {
         var base64Decoder : Base64Decoder = new Base64Decoder();
         base64Decoder.decode(pixelData);

         var byteArray : ByteArray = base64Decoder.toByteArray();
         byteArray.position = 0;
         byteArray.uncompress();

         var loader : Loader = new Loader();
         loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeListener);
         loader.loadBytes(byteArray);
      }

      private function completeListener(event : Event) : void
      {
         bitmapDataCache = (LoaderInfo(event.target).content as Bitmap).bitmapData;
         this.bitmapData = bitmapDataCache;
      }

      private function get pixelData() : String
      {
         var dataXML : XML = <![CDATA[
{data}
         ]]>;

         return dataXML.toString();
      }
   }
}

Nachdem jetzt das Bild mit FileReference geladen ist, wird wie schon erwähnt das Bitmap in ein ByteArray gespeichert:

private function generateByteArrayFromBitmap() : void
{        
   var graphicEncoder:PNGEncoder = new PNGEncoder();
   
   _byteArray.position = 0;
   _byteArray = graphicEncoder.encode(_pictureData);
}

Als nächstes wird dieses ByteArray noch leicht komprimiert mit:

private function compressByteArray() : void
{
   _byteArray.position = 0;
   _byteArray.compress();
}

Jetzt wird die Klasse erzeugt. Es wird der {data}-Block im Template-String ersetzt.
Der Inhalt besteht aus dem Base64 kodierten String des ByteArray.

private function generateClass() : void
{
   var myPattern : RegExp = /{data}/s;
   
   _template = _template.replace(myPattern, replaceFunction);
   
   function replaceFunction() : String
   {
      var base64Encoder:Base64Encoder = new Base64Encoder();
      base64Encoder.encodeBytes(_byteArray);
     
      var encodedData : String = base64Encoder.flush();
         
      return "\t\t\t\t"+encodedData.split("\n").join("\n\t\t\t\t");;
   }
}

Das ganze als FDT-Projekt gibt es hier:
IconizedClass-2010-05-26.zip

Kommentar schreiben

    Warum diese Frage?