0 Replies Latest reply on Aug 25, 2010 9:17 AM by mynormalnamesarenotavail

    BitmapData, get/setPixel on scaled data. Real get/setPixel exist?

    mynormalnamesarenotavail

      Ok... I've been staring at this all day long, so the answer might be screaming at me and I just don't see it....

       

      Summary:  I need an Image to "show through" to the background, cutting through any other images that may be in it's way -- but not images on top of it (only below).

       

      [Edit: Is there an on-screen get/setPixel alternative?  As it seems BitmapData's only let's you edit the raw (un-transformed) data.  I'd like to just write the actual pixels on the screen.  There has to be something that keeps track of all the pixels when the item is scaled.  ]

       

      A picture is worth a thousand words, so I whipped up some examples in PS:

       

      Imagine this is the app that consists of four Images.  The background (skyline), and the three layers stacked on top.  The smiley is the backmost, the heart is the frontmost, and the snowman is in the middle.

      example1.jpg

       

       

       

      Notice how the snowman knocks out the smiley, but not the heart.  I'm achieving this by painting BitmapData with the background pixels wherever the clipart is not transparent. Also, if there was an additional layer (or any number of layers) "behind" the smiley, it would also be "knocked out" by the snowman.  This is why I'm pretty sure I have to do it this way with the BitmapData and manual get/setPixel. (Open to suggestions?)

       

      This method does work perfectly... as long as the snowman isn't scaled or rotated.

      example3.jpg

       

       

       

      Here, the snowman has been scaled up and rotated.  The problem is that the background image pixels get scaled up right along with the art. The outline of the snowman should only be visible when it knocks out the smiley, but instead you can see it clearly because the background pixels do not match, and are actually scaled/rotated along with the snowman.

       

      example5.jpg

       

       

       

      This is how it should look even with the scaling and rotating.

      example6.jpg

       

       

      Here is the code that is doing the "reverse mask":

       

      this == Image
      
      var thisWidth:uint      = this.width;
      var thisHeight:uint      = this.height;
      var targetWidth:uint      = this.x + thisWidth;
      var targetHeight:uint      = this.y + thisHeight;
           
      var data:BitmapData = Bitmap(backgroundImage.content).bitmapData;
      var newdata:BitmapData = new BitmapData(thisWidth, thisHeight, true, 0);
      newdata.draw(this);
                     
      this.content.visible = false;
                     
      newdata.lock();
                     
      for ( var x:uint = this.x, drawX:uint=0; x < targetWidth; x++,drawX++ ) {
                          
           for ( var y:uint = this.y, drawY:uint=0; y < targetHeight; y++,drawY++ ) {
      
                color = data.getPixel(x, y);
                newdata.setPixel( drawX, drawY, color );
      
           }
                          
      }
                     
      newdata.unlock();
                     
      this.addChild( new Bitmap(newdata) );
      
      

       

      Anyone have any suggestions?

       

      My current direction is....

       

      1)  Is there a way to rasterize a transformed layer?  By that I mean make the current transformation permanent.  So, if an image was scale(1.5, 2)  you could function rasterize(image) and it would still stay scaled, but have scale(1, 1)

       

      2) Do the calculations to figure out the inverse matrix and apply it to the bitmapdata before adding it as a child of the image.  This way, when the background pixels get scaled/rotated, they will end up in the right place.

       

      3) Give up, quit my job, buy a sailboat and a lifetime supply of rum.