Skip to main content
Amy Blankenship
Legend
December 16, 2009
Answered

BitmapData.draw() failing to draw entire MovieClip

  • December 16, 2009
  • 3 replies
  • 1308 views

Hi, all;

I'm trying to do some lean blitting for an object that rotates by rotating it once at startup and capturing a BitmapData snapshot of each 5 degrees.  The problem I'm having is that the draw() method of the BitmapData object is only picking up pixels in the MovieClip that are below and to the right of the registration point.  If I change the MC so that the registration point is in the top left corner, I sometimes get what looks like most of the pixels, but the entire object rotates into and out of the frame, since it's rotating around the corner and not the center.

Has anyone encountered this before, and if so is there a fix?

Thanks;

Amy Blankenship

flexdiary.blogspot.com

This topic has been closed for replies.
Correct answer

BitmapData information.

BimapData will and can only caputure un-adjusted bitmaps and always from the origin point at TopLeft.

Though it might sometimes seem like the bitmap captured filtered effects or rotating, the thing is it did not at least on the object that the draw was targeted.

If the children of the drawn object have rotated objected and filters etc they will appear in the draw as they were as Children.

To rotate something lets say bitmap because you're blitting,  that image will have a top LEft origin point.  rotating even 180 degrees will actually mess up your draw.

because at the top left origin point is where you will be rotating around.. not the center.  so when you draw this image, it will still ONLY draw with is to the right and below 0,0

This must be taken into account whenever you draw.

therefor, start by centering your bitmap with translate(-bitmap.width*.5,-bitmapHeight*.5)

var matrix:Matrix= new Matrix()

     matrix.translate(-bitmap.width*.5,-bitmapHeight*.5)

     matrix.rotate(90 * (Math.PI / 180))

matrix.translate(bitmap.width*.5,bitmapHeight*.5)

draw(bitmap,matrix) 

whoops swap bitmapHeight and width

3 replies

Amy Blankenship
Legend
December 16, 2009

OK. I screwed up the translation logic and it caused the weird amoeba .

This gets me closer, but it's not as "clean", since my object has a thick stroke and it's hard to get its actual pixel width to make the rotation accurate.

Thanks!

Amy Blankenship
Legend
December 16, 2009

I think you're misunderstanding the question.  I am using a matrix to transform it, and that lower right quadrant of the MovieClip rotates perfectly as inended, but the rest of the object isn't captured as if it weren't there.

Here's the code:

package com.magnoliamultimedia.datastructures
{
import flash.display.BitmapData;
import flash.display.IBitmapDrawable;
import com.magnoliamultimedia.datastructures.IChain;
import com.magnoliamultimedia.datastructures.IChainable;
import flash.geom.Matrix;
import flash.geom.Rectangle;

/**
  * RotationChain takes an IBitmapDrawable and rotates
  * it through 360 degrees, creating a BitmapDataLink
  * for each incremental rotation
  * @author Amy Blankenship
  */
public class RotationChain implements IChain
{
  //private storage for the chain entry point
  private var _defaultNode:IChainable;
  /**
   * Constructor
   * @param rotatingObj object to rotate
   * @param degrees number of degrees to rotate (must divide evenly into 360)
   */
  public function RotationChain(rotatingObj:IBitmapDrawable, degrees:int=5, size:int=200)
  {
   //first, check if degrees divides evenly into 360
   if (360 % degrees != 0) {
    throw new Error('Degrees must divide evenly into 360');
    //set to the default, so we still have a usable chain
    degrees = 5;
   }
  
   var matrix:Matrix = new Matrix();
   var bd:BitmapData;
   var bdl:BitmapDataLink;
   var lastBDL:BitmapDataLink;
   var loops:int = 360 / degrees - 1;
   for (var i:int = 0; i < loops; i++) {
    /* Take "snapshot" of rotating obj with matrix applied.
     *  On the first loop, use the identity matrix.
     */
    bd = new BitmapData(size, size);
    bd.draw(rotatingObj, matrix);
    bdl = new BitmapDataLink(bd);
    //check for any previous links that might have been added
    if (lastBDL == null) {
     //no? this is the default
     defaultNode = bdl;
    } else {
     //set up reciprocal arrangement with last node
     bdl.previous = lastBDL;
     lastBDL.next = bdl;
    }
    //set this link as the last link
    lastBDL = bdl;
    //rotate next snapshot
    matrix.rotate(degrees);
   }
   //connect the last link to the first link to make a circular chain
   lastBDL.next = defaultNode;
   defaultNode.previous = lastBDL;
  }
 
  /* INTERFACE com.magnoliamultimedia.datastructures.IChain */
 
  public function get defaultNode():IChainable
  {
   return _defaultNode;
  }
 
  public function set defaultNode(value:IChainable):void
  {
   _defaultNode = value;
  }
 
}

}

Is there anyone out there who does this kind of stuff?

Thanks;

Amy

kglad
Community Expert
Community Expert
December 16, 2009

the draw() method "draws" the untransformed movieclip.  in your situation, that's the unrotated movieclip.

to "draw" the rotated movieclip use the matrix parameter in the draw() method.

Correct answer
December 16, 2009

BitmapData information.

BimapData will and can only caputure un-adjusted bitmaps and always from the origin point at TopLeft.

Though it might sometimes seem like the bitmap captured filtered effects or rotating, the thing is it did not at least on the object that the draw was targeted.

If the children of the drawn object have rotated objected and filters etc they will appear in the draw as they were as Children.

To rotate something lets say bitmap because you're blitting,  that image will have a top LEft origin point.  rotating even 180 degrees will actually mess up your draw.

because at the top left origin point is where you will be rotating around.. not the center.  so when you draw this image, it will still ONLY draw with is to the right and below 0,0

This must be taken into account whenever you draw.

therefor, start by centering your bitmap with translate(-bitmap.width*.5,-bitmapHeight*.5)

var matrix:Matrix= new Matrix()

     matrix.translate(-bitmap.width*.5,-bitmapHeight*.5)

     matrix.rotate(90 * (Math.PI / 180))

matrix.translate(bitmap.width*.5,bitmapHeight*.5)

draw(bitmap,matrix) 

whoops swap bitmapHeight and width

Amy Blankenship
Legend
December 16, 2009

KGlad, I tried what you said, just in case it would work, and my movieclip (which is a Flash vector of a traditional yellow and black smiley face) blew up and became sort of like a rotating black amoeba that occasionally got an edge clipped.

Thanks;

Amy