Archive for the 'AS2' Category

Inverting the alpha of a bitmap image

Friday, November 30th, 2007

A piece of code and a demo says more than a thousand words :). This code demonstrates inversion of an alpha channel in Flash8/AS2.

  1. /**
  2. * This example demonstrates inverting an alpha channel on an image.
  3. * Since Flash premultiplies the alpha, we need to keep two separate images: one with the color data, and
  4. * one with the alpha data. It demonstrates splitting the alpha from an image, inverting and proves
  5. * premultiplying the alpha destroys color information.
  6. *
  7. * @author J.C. Wichman / Objectpainters.com
  8. */
  9.  
  10. import flash.geom.Rectangle;
  11. import flash.geom.Point;
  12. import flash.display.BitmapData;
  13. import flash.filters.ColorMatrixFilter;
  14.  
  15. //set up some default params for the images
  16. var width:Number = 100;
  17. var height:Number = 100;
  18. var fillColor:Number = 0x000000;
  19.  
  20. /**
  21. * Simple function that checks how many bitmaps have already been shown on stage and
  22. * bases the location for the next one on that information. Never use code like this
  23. * out of context, since its bad programming practice:).
  24. */
  25. function showBitmap (pBitmap:BitmapData, title:String) {
  26. var imageCount:Number = this.getNextHighestDepth();
  27. var row:Number = Math.floor (imageCount/3);
  28. var columns:Number = imageCount%3;
  29.  
  30. var newClip:MovieClip = this.createEmptyMovieClip("image"+imageCount, imageCount);
  31. newClip.attachBitmap(pBitmap, 0);
  32. newClip.createTextField("title", 1, 0, 110, 10,10);
  33. var textClip:TextField = newClip["title"];
  34. textClip.autoSize = true;
  35. textClip.text = "Image "+imageCount+":\n"+title;
  36. var tf:TextFormat = new TextFormat();
  37. tf.font = "Arial";
  38. tf.align ="center";
  39. textClip.setTextFormat(tf);
  40.  
  41. newClip._x = (columns * 150)+10;
  42. newClip._y = (row * 170)+10;
  43. }
  44.  
  45.  
  46. //setting up demo rgb image, this is an image without alpha.
  47. //Since flash uses premultiplied alpha, adding an alpha channel will ruin the image for
  48. //further use when we want to invert the alpha channel, so we keep colours separate from alpha
  49. //(omg pink shirts!)
  50. var colorImage:BitmapData = new BitmapData(width, height, false, fillColor);
  51. for (var x = 0; x < width; x++) {
  52. for (var y = 0; y < height; y++) {
  53. //fiddle with the pixel data to show a dark gradient
  54. colorImage.setPixel( x,y, x<<16|y<<8|x+y);
  55. }
  56. }
  57. showBitmap (colorImage, "Colour w/o alpha");
  58.  
  59. //now we create a demo alpha bitmap. All color info is non existent, only
  60. //alpha data is set. When x<y the alpha value is near opaque, otherwise its near transparent.
  61. //we only use 0xAF and 0x10 instead of 0xFF and 0x00 to show partial alpha values are inverted ok as well
  62. var demoAlpha:BitmapData = new BitmapData(width, height, true, fillColor);
  63. for (var x = 0; x < width; x++) {
  64. for (var y = 0; y < height; y++) {
  65. demoAlpha.setPixel32( x,y, (x<y?0xAF:0x10)<<24);
  66. }
  67. }
  68. showBitmap (demoAlpha, "Alpha only");
  69.  
  70. //now imagine you didnt have a separate alpha bitmap to start with, but a starting image with alpha
  71. //which you needed to extract first:
  72. var alphaSplit:BitmapData = new BitmapData(width, height, true, fillColor);
  73. //copy the alpha channel of one image to another image
  74. alphaSplit.copyChannel(demoAlpha, new Rectangle(0,0, width, height), new Point(0,0), 8,8);
  75. showBitmap (alphaSplit, "Alpha channel copy\n (same as previous)");
  76.  
  77. //now we are going to invert the alpha. This can be done on a pixel by pixel basis, but this might just
  78. //be faster, you'd have to test it
  79. var alphaInvert:BitmapData = alphaSplit.clone();
  80. var matrix:Array = new Array();
  81. matrix = matrix.concat([1, 0, 0, 0, 0]); // red
  82. matrix = matrix.concat([0, 1, 0, 0, 0]); // green
  83. matrix = matrix.concat([0, 0, 1, 0, 0]); // blue
  84. matrix = matrix.concat([0, 0, 0, -1, 0xff]); // alpha, negate the alpha and add 255
  85. alphaInvert.applyFilter(alphaInvert, alphaInvert.rectangle, new Point(0, 0), new ColorMatrixFilter (matrix));
  86. showBitmap (alphaInvert, "Inversion of \nalpha channel");
  87.  
  88. //now the real action, we combine our original color pixels with the inverted alpha channel
  89. var comboImage:BitmapData = new BitmapData(width, height, true, fillColor);
  90. comboImage.copyPixels(colorImage, colorImage.rectangle, new Point(0,0), alphaInvert, new Point(0,0));
  91. showBitmap (comboImage, "Colours + \ninverted alpha");
  92.  
  93. //now to prove premultiplied alpha destroys color information:
  94. var colorImgWithAlpha:BitmapData = new BitmapData(width, height, true, fillColor);
  95. for (var x = 0; x < width; x++) {
  96. for (var y = 0; y < height; y++) {
  97. //fiddle with the pixel data to show a dark gradient
  98. colorImgWithAlpha.setPixel32( x,y, (x<y?0xfe:0x01)<<24|x<<16|y<<8|x+y);
  99. }
  100. }
  101. colorImgWithAlpha.applyFilter(colorImgWithAlpha, colorImgWithAlpha.rectangle, new Point(0, 0), new ColorMatrixFilter (matrix));
  102. showBitmap (colorImgWithAlpha, "Colour with\n premultiplied \n inverted alpha");
  103.  
  104.  
  105.  

Casting to Array

Friday, November 16th, 2007

Casting to Array, well that’s easy enough right?

Imagine you have:
var my2dArray:Array = new Array();

my2dArray.push ([1,2,3,4,5]);
my2dArray.push ([6,7,8,9,0]);

And now you want to access and cast an element of myArray to an array:

var firstArray:Array = Array (my2dArray[0]);
trace (firstArray.length);

Right?

Yeah if you’re compiling in MTASC. The Flash IDE (more…)

Ideas for asset and code separation

Wednesday, November 14th, 2007

I had an idea this afternoon for simple asset from code separation in Flash8/AS2. You might have been in the situation were you wanted to load in your views, or have your views and other assets external from your code. If these assets happened to be V2 Components you were even having a bigger party.

I am usually working on a kind of hybrid projects, I create a fla with assets and code runnable from the IDE, and use the resulting swf as an injection swf in FlashDevelop. The cool thing of working this way is that -seeing the project is hybrid and all- you can either work on the project in the Flash IDE, or crank some code in FlashDevelop. There are a few drawbacks however.

  • you are using an swf which already contains all code as an injection swf. Since we use only intrinsic mx classes, we can’t use the keep flag to remove all classes from the swf, since we lose the mx classes from the swf. However especially refactoring where new superclasses are introduced or interfaces, requires recompilation of the injection swf in the Flash IDE. And in general it’s bad practice, and bloates your swf
  • you need the code to export the swf from the IDE
  • you need the injection swf to run your application from FlashDevelop

Especially when working with a designer where the designer (more…)

220-BPM - a new flash framework is born

Monday, November 12th, 2007

I had an idea for a flash framework, and while I’m not fully there yet, the first of proof concepts at TriMM are very promising. It solves a lot of the problems I can think of up till now, so I’m curious to see where this will go.

Design patterns were clear enough, but their implementation is often less than straightforward. Take an MVC pattern. Have you ever found one straightforward implementation? Instead of 100k hits on google all with a slightly different twist? The same patterns that should make it easier to communicate with your coworkers come back to haunt you, since responsibilities in classes are slightly differently allocated than you are used to, mediators are called controllers, and everything is untyped or abstracted away for the sake of ’simplicity’ etc…

The ideas I’m currently having are in blueprint phase including an almost working example as well. Just a quick overview of the design goals that are (more…)

Flash Frameworks Revisited

Saturday, October 20th, 2007

On my long list of plans for this year was to dive into the world of Flash Frameworks.
Only thing is that it has taken me so long, that the world has moved on to Flex Frameworks, but that’s beside the point.

I wanted to dive into frameworks because I heard all these people talk about how great frameworks are and how they’ve helped people build great applications etc.

A quick recap of my first impressions/experiences: (more…)

Wrapping function calls in AS2

Friday, August 24th, 2007

Also known as:

  • debugging function calls
  • displaying the name of a called function
  • tracing function calls director like

Today I finally got to try something I had been wanting to try for a long time: wrapping function calls in a nice way.

I had been playing around with function pointers etc, which was ok in itself, but I was forced to create the messy pointer bit each time over again. So today I implemented a FunctionWrapper class.

Say we have a class Test, with a method testMethod.

Now we want to execute some code before calling testMethod and after calling testMethod. “Well write another function to do so”, you might say. Of course that is one option, but assume we are looking for another way to do so (I’ll discuss some scenario’s in a minute).

Using function pointers you can let the Test.testMethod reference point to your own method and from your own method execute the original method, pre and postpending it with some functionality. I think this is a bit like the AOP mechanism, but I’m not too sure since I am a composition filter freak by nature :) .

The FunctionWrapper class takes care of all this reference shuffling for you:

FunctionWrapper.wrap (
TestClass,
"testMethod",
_preFunction,
null, //no additional args to pre
_postFunction,
null //no additional args to post
);

Now I won’t explain a lot more about that on this page, since I’ve got an example for download here, which contains all required classes and documentation. Note that the example requires some support classes (more…)

Local Flash Content And SSL

Tuesday, August 14th, 2007

We are in the process of migrating one of our largest eLearning systems to SSL and Active Directory. Some of the Learning Objects within this system are pretty complex and I’ve implemented a mechanism which allows you to test them standalone.

However during the migration to SSL these objects stopped working when run locally, from the IDE or from FlashDevelop.

I tried to wrap my head around why this was happening, since I’ve been doing less and less with serverside content and certificates these past few years.

Luckily I found this URL which described the problem quite accurate.

Http:// content cannot always access https:// content it seems, but the invalid security certificate was the biggest issue for us.

Our system admin Roy Olthof quickly jumped in, installed a valid certificate and tadaaaaa. Local content could access https content again. Note that we were accessing https content on our own test server, which didnt have a certificate installed.

In addition the Flash content kept giving me the mixed content (secure and unsecure) warning. After changing all the http://’s in the macromedia/adobe codebases (contained within the object and embed tags) this disappeared as well.

Drawing using controlpoints

Wednesday, July 18th, 2007

There is an old trick which comes down to drawing a fluid line through controlpoints, by using the average of the controlpoints as anchors.

As usual most of my blogging is triggered by post on the flashcoders list, making me want to try things for myself. This has probably been done a million times, but here is my quick and dirty go at it:

You can download the example here.

arguments.callee._name?

Monday, July 16th, 2007

A question on the flashcoders list about an hour ago triggered me to put together a very simple example that I have been wanting to put together for ages now.

How do you get the name of a function?

With function we could refer to:

  • any function
  • a calling function
  • a function being called
  • My reflection package is at the core of my xflas2 logger, but I don’t think a lot of people have been using it. Even though it provides much the same information MTASC can put into a trace statement WITHOUT MTASC (except for the linenumbers). Not that I don’t like MTASC, I absolutely love MTASC and never leave home without it ;-).

    Anyway, the reflection package is perfectly capable of being used standalone without my logger or Xray around (yeah that’s right: osflash.org/xray yeah baby!). It provides two simple classes with an even simpler API: ClassFinder and FunctionFinder.

    Imagine a function:


    private static function runExample3() {
    _print (
    "I am :"+
    FunctionFinder.getFunctionName(arguments.callee)+
    " and I am defined in "+
    ClassFinder.getClassName(
    FunctionFinder.getFunctionClass(arguments.callee)
    )+
    " and OH YEAH I was called by "+
    FunctionFinder.getFunctionName(arguments.caller)
    );
    }

    Note that it’s static, but it doesn’t have to be, I’m just being a lazy git.

    This prints:


    I am :runExample3 and I am defined in SampleClass and OH YEAH I was called by main

    Now, for the small print : you HAVE to call ClassFinder.registerAll() once somewhere at the start of your program.

    For your convenience I’ve put an example together for download, have fun and let me know what you think of it!

    Note:
    I am working on an (xuse da tude but I’ve been very happy with it so far) awesome new version of a reflection package, which doesn’t have the registerAll requirement, but I’m not quite there yet so for now this will have to do :).

    Preventing dynamic property collision

    Monday, July 9th, 2007

    We sometimes have to deal with dynamically added properties at runtime, and looking into the code of some frameworks, we are not alone in this. However, whereas our packages are carefully structured to provide classname collisions (according to the standard reversed domain name convention), my experience is that developers take no such precaution when it comes to adding properties to objects at runtime.
    So it’s very probable for two different frameworks to add say a “className”, or a “hashCode” or a “key” property to classes or objects.

    Now the odds of using two frameworks together might seem slim, but on the other hand its a very subtle bug waiting to happen. You might not be using 2 frameworks, but you might use a component based on another framework loaded at runtime that does etc.

    I dont know if any of you are using any convention to prevent this, but we have recently started to use a very simple convention to make sure this doesnt happen, and I thought I’d share it.
    Instead of object[”key”] or object[”className”] etc we have recently started to define these as:
    private static var _key:String = “_”+[insert classname here]+”.”+[insert propertyname here]

    so for example:

    private static var _key:String =
    "_nl.trimm.util.SessionUniqueIdentifier.key";

    and then later on

    myObject[_key] = ....

    I’d like to hear if there are any of you who are using similar conventions or how you deal with this ‘problem’ (problem is a too big of a word for such a minor detail, but still).

    Some of the subtle errors on collisions like this are 256 recursion errors, hanging applications, not working in general etc.
    In my opinion a convention like this is especially important for sources you plan to release to a bigger audience, where these sources act upon the properties of all classes and objects from somewhere other than the class or object itself. As said above classes that fall into these categories are hashcodefactories, reflection utilities, wrappers and there might be more.