Cut Image Into Squares

Actionscript:
  1. [SWF(width=650, height=650)]
  2. var loader:Loader = new Loader();
  3. loader.load(new URLRequest("http://actionsnippet.com/wp-content/chair.jpg"));
  4. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
  5. x = y = 25;
  6. var w:Number;
  7. var h:Number;
  8. var rows:Number = 20;
  9. var cols:Number = 20;
  10. var tiles:Vector.<Sprite> = new Vector.<Sprite>();
  11. function onLoaded(evt:Event):void{
  12.     w = evt.target.width;
  13.     h = evt.target.height;
  14.     var image:BitmapData = Bitmap(evt.target.content).bitmapData;
  15.     var tileWidth:Number = w / cols;
  16.     var tileHeight:Number = h / rows;
  17.     var inc:int = 0;
  18.     var pnt:Point = new Point();
  19.     var rect:Rectangle = new Rectangle(0,0,tileWidth,tileHeight);
  20.     for (var i:int = 0; i<rows; i++){
  21.         for (var j:int = 0; j<cols; j ++){
  22.              var currTile:BitmapData= new BitmapData(tileWidth, tileHeight, true, 0x00000000);
  23.              rect.x = j * tileWidth;
  24.              rect.y = i * tileHeight;
  25.              currTile.copyPixels(image, rect, pnt, null, null, true);
  26.              var bit:Bitmap = new Bitmap(currTile, "auto", false);
  27.              var s:Sprite = tiles[inc] = Sprite(addChild(new Sprite()));
  28.              // offset them a little bit to show that they are in fact tiles.
  29.              s.x = rect.x + Math.random()*10 - 5;
  30.              s.y = rect.y + Math.random()*10 - 5;
  31.              
  32.             /* If you have TweenLite, try something like this:
  33.              s.x = rect.x;
  34.              s.y = rect.y;
  35.              TweenLite.from(s, 0.3, {x:Math.random()*stage.stageWidth, y:Math.random()*stage.stageHeight, alpha:0, delay:inc / 50});
  36.              */
  37.              s.addChild(bit);
  38.              inc++;
  39.         }
  40.     }
  41. }

This snippet shows how to cut a dynamically loaded image up into small squares (or rectangles). Each square is placed into a sprite and these sprites are stored in a vector for later use. This kind of thing could be useful in conjunction with tweening engines to create transition effects. If you have TweenLite on your machine you could add the import statement "import gs.TweenLIte" and uncomment lines 33-35.

For the purposes of this demo I just offset each sprite slightly to show that it the loaded image has in face been cut up. Here are a few stills with created by altering the rows and cols variables:

Without any animation, this snippet is a bit boring - again, using TweenLite or some other tweening engine is the way to go.

This entry was posted in BitmapData, external data and tagged , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

12 Comments

  1. samBrown
    Posted July 13, 2009 at 2:37 pm | Permalink

    good stuff! thanks!

  2. Posted July 13, 2009 at 3:53 pm | Permalink

    hey there, looks pretty cool. just one thing is bothering my mind:
    var s:Sprite = _tiles[inc] = Sprite(addChild(new Sprite()));

    would you quickly explain it to me? i’m just not getting it somehow :/
    thanks in advance!

  3. Posted July 13, 2009 at 3:58 pm | Permalink

    Sure…

    Sprite(addChild(new Sprite()));

    create a new sprite and add it to the display list

    _tiles[inc] =

    set tiles[inc] equal to that newly created sprite

    var s:Sprite =

    set a temp variable called “s” equal to the newly created sprite.

    That’s it, create a sprite and store two references to it… one in the tiles vector and the other in the temp var “s”.

  4. Posted July 13, 2009 at 4:03 pm | Permalink

    well, differently asked… what´s the difference to:
    _tiles[inc] = new Sprite();
    var s:Sprite = _tiles[inc];
    addChild(_tiles[inc]);

    aside the line-count? hm, well, maybe i just don’t get the sprite-cast on addChild(new Sprite()); ?!

  5. Posted July 13, 2009 at 4:07 pm | Permalink

    now i’ve got it, haha. okay, i’m sorry :)

  6. Posted July 13, 2009 at 6:58 pm | Permalink

    yeah, I have a habit of consolidating lines on some snippets…. there is no advantage to it and it can sometimes reduce readability ;)

  7. Posted July 14, 2009 at 1:51 am | Permalink

    I’ve been trying this myself, and have a feeling that your way might be slightly more efficient - I’ll have to test it out. I’ve been using this type of thing with a particle system, to make display objects destructible - http://lawriecape.co.uk/theblog/flash-content/explosions/

  8. Posted July 14, 2009 at 7:06 am | Permalink

    that looks nice… the main things that you can consider if your trying to improve speed of this … is the fact that BitmapData.draw() is way slower than BitmapData.copyPixels() … also, any instantiation that you can do beforehand should be done…

  9. Posted July 15, 2009 at 2:37 am | Permalink

    Thanks Zevan.
    I’ve managed to squeeze some more performance out of it today. I’d been trying to use copyPixles() over draw() where possible - but had missed it on the recursive breaks. Cheers!

  10. Ricardo
    Posted August 2, 2009 at 5:45 pm | Permalink

    Maybe you should use Math.ceil when calculatin tileWidth and tileHeight to make shure you won’t loose any column or row of pixel in a rounding stuff from flash.

  11. Phil
    Posted April 19, 2010 at 10:24 am | Permalink

    Could this be achieved in AS2?

  12. Posted April 21, 2010 at 9:17 pm | Permalink

    yes but it is a good deal harder to do.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*