Marty
Marty

Reputation: 39456

How can I quickly rotate the pixels that make up BitmapData without using BitmapData.draw()?

I've been using BitmapData.copyPixels() to draw graphics onto a canvas (Bitmap).

I need to rotate the resulting graphics without the use of draw() because it's vastly slower.

How can I rotate the target graphic? I'm assuming that there might be a formula or library that I can use which will first reorganize the pixels that make up a graphic based on an origin (point) and radians.

I'm pretty certain that I'm not capable of creating such logic, so if there are any known libraries that do this, that would be awesome.

I'd like to achieve something similar to XNA's SpriteBatch.Draw() method, which accepts rotation as its 5th argument.

Upvotes: 2

Views: 2141

Answers (3)

bummzack
bummzack

Reputation: 5875

copyPixels basically just copies memory blocks from one BitmapData object to another. Transforming the pixels (eg. scaling, rotating, shearing etc.) is way more CPU intensive. That's just how things are and there's no magic method to change this. Even if you would find another library that does these things, I doubt it will be any faster than the native implementation as it would have to be implemented in pure ActionScript and cannot be optimized as the native commands are.

If you're blitting your scene (eg. copy sprites to a larger BitmapData canvas) and you have to perform a lot of rotations with lots of sprites, then the best way would be to render a discrete amount of render steps to a BitmapData and then use copyPixels to copy the rotation that is closest to your desired rotation. That way you would use the slow draw only once at initialization and then use the fast copyPixels from there on.

There's another way for drawing rotated bitmaps, by using the new 3D API, you could simply render textured quads which you can rotate, scale and move to any extent without performance drops. This would be the closest to XNAs draw implementation, but it would require you to dump the blitting (draw to a Bitmap) entirely.

Overall I would go with the simplest way and just use BitmapData.draw. Create a test-case that draws your estimated maximum of concurrent sprites and profile it to see if the performance-impact is so large that it's worth implementing any of the mentioned workarounds.

Upvotes: 4

iND
iND

Reputation: 2649

Some ideas, but speed is untested:

  • If the rotations are fixed (e.g., every 30 degrees), create a sprite sheet with the different rotations, and use copyPixels().
  • Make the bitmapdata into a bitmap, and rotate the bitmap in front of the other graphics. Use an object pool to avoid instantiation costs, if there are going to be frequent removals/additions. Use cacheAsBitmapMatrix to make rotations a bit faster, though there is more memory usage.
  • Look into making a Shader that does the rotation.
  • Don't rotate the bitmapdata . . . rotate the world around it.
  • Make the animation really, really slow, so no one notices. This is actually good advice if you can get away with it . . . reduce the framerate until the blitting affects are unnoticeable.

Upvotes: 0

ToddBFisher
ToddBFisher

Reputation: 11600

I would use a matrix. There are many examples online, I like this one, it is short and to the point. http://www.psyked.co.uk/actionscript/rotating-bitmapdata.htm

Upvotes: 2

Related Questions