Solution to Flex Image Rotation and Flipping around Center

Main menu:

Topics

Recent Posts

Blog

March 2010
M T W T F S S
« Feb   Apr »
1234567
891011121314
15161718192021
22232425262728
293031  

Past Posts

Java/Java EE

JDBC

Other

Solution to Flex Image Rotation and Flipping around Center

March 17th, 2010 by Scott Selikoff
Today, I was trying to rotate and flip an image around its center point in Flex and the solutions I came across on the web didn’t seem to do the trick. For images that have been previously dragged/dropped, resized, rotated, or translated, the existing solutions are simply not sufficient. With that in mind, I’ve written a solution for rotating and flipping an image around its center that works perfectly in all situations.




The Code

Without further ado, here’s the solution:

private static function rotateImage(image:Image, degrees:Number):void {
	// Calculate rotation and offsets
	var radians:Number = degrees * (Math.PI / 180.0);
	var offsetWidth:Number = image.contentWidth/2.0;
	var offsetHeight:Number =  image.contentHeight/2.0;

	// Perform rotation
	var matrix:Matrix = new Matrix();
	matrix.translate(-offsetWidth, -offsetHeight);
	matrix.rotate(radians);
	matrix.translate(+offsetWidth, +offsetHeight);
	matrix.concat(image.transform.matrix);
	image.transform.matrix = matrix;	
}

Also, here’s a related function to perform a horizontal (left to right) flip of an image:

private static function flipImage(image:Image):void {
	// Calculate offset
	var offsetWidth:Number = image.contentWidth/2.0;
	var offsetHeight:Number =  image.contentHeight/2.0;

	// Perform horizontal flip
	var matrix:Matrix = new Matrix();
	matrix.translate(-offsetWidth, -offsetHeight);
	matrix.scale(-1, 1);  // change to matrix.scale(1,-1) for vertical flip
	matrix.translate(+offsetWidth, +offsetHeight);
	matrix.concat(image.transform.matrix);
	image.transform.matrix = matrix;
}


The Problem Explained

The problem, in a nutshell, is that Flex maintains the top left corner of the image for all transformation and ignores the center point. For example, just calling the rotate() method will produce rotations around the corner such as in this example. Many almost-solutions, see here and here, resolve this by first moving (translating) the image around its center by using the image’s vertical and horizontal midpoint.

A more complex issue arises, though, when the image is no longer positioned at its anchor, or in technical speak the image’s transformation tx/ty values are not 0. I found once you sufficiently drag/drop, rotate, or otherwise modify the image, all of the solutions tend to fall apart. In my situation, all the images were oriented with tx/ty referring to the anchor of the canvas, making these previous solutions difficult to rely upon.

The Solution Explained

After some fun manipulating matrices, I’ve written and tested a solution that will properly rotate an existing image around its center regardless of where it is positioned on the canvas or what transformations have been performed on it. It starts by applying rotation around the image’s center to the identity matrix. In this way, it simulates rotating the matrix around its midpoint translated position, but it is actually applied to the identity matrix. Once the rotational matrix has been calculated, the image is stuck at the top of the canvas. What we really need is a matrix that will take the rotational matrix we’ve just calculated and apply all the previous transformations to orient/rotate the image in the proper position. Well it so happens we have such a matrix, the image’s transformation matrix in fact! So, we apply the transformation matrix of the image to our calculated rotational matrix and voila! The result is our transformed image rotated by the specified amount around its center. We just set the image’s transformation matrix to this result and we are done.

Comments

Comment from Dan Z
Posted: May 6, 2010 at 12:28 pm

Thank you! Have you looked at this for 3D rotation?

Comment from Alex R
Posted: May 18, 2010 at 7:44 pm

Great !! worked perfect. Although, i’m using a custom component to resize the image and the x,y anchor points are on the right top instead con the default left top after flipping. I’ve been searching and didn’t found anything close to reassigning anchor points to an image in flex. Any ideas would be greatly appreciated !!!

Comment from JimP
Posted: May 23, 2010 at 12:50 pm

Matrices are a total mystery to me.

What online reference(s) to you recommend Flex developers study in order to to get a basic understanding of WTF these matrix thingies are, and how to manipulate them? I don’t want a graduate-level course in arcane mathematics — just the basic recipes.

Comment from Carlos
Posted: September 7, 2010 at 9:04 pm

Hi Scott – thanks a lot for a perfect solution!

+1 also for providing the code clean and ready to be used.

Comment from Bill
Posted: June 28, 2011 at 6:58 pm

Scott, thanks for taking the time to do such a needed flash/flex task and to post it here on your site. Matrices are not my strong point. I found an interesting anomoly that might even make your code more universally useable for images if you tweak it. I tried your rotation function with some square thumbnails and it worked perfectly, but when I tried it with non-square images, the images that I was saving to my hard drive were offset in an odd fashion. After staring at the few lines of code forever, it finally came to me. When you offset the image in the x and y directions to rotate the image about its center, after the rotation, you can no longer offset it back using the same offsets because the width and height now have switched places. You can use your function for both square and non-square images if you simply switch the offsets in the code in line 11 to:

matrix.translate(+offsetHeight, +offsetWidth);

Let me know if I am in error, but this worked for me. Thanks.

Comment from vargazso
Posted: October 4, 2011 at 3:42 pm

Hi, I’m using the above code to rotate and zoom images (SWF images). Currently I’m facing with a problem, where some of the SWF graphics are rotating and zooming perfectly, but there are some image, where this is not working. Graphics are jumping out of screen without controll. The only difference between the good and bad swf objects is the filetype. 7.0 is good others are not so :o( . Tried to convert objects to 7.0 but this is not working also. Have You ever seen this type of problem? Where can I find any solution for it? Any suggestion, what could be wrong? Many thanks in advance, Zsolt

Comment from jameel
Posted: August 29, 2012 at 6:55 am

You rock dude!!!!Thanks a lot. This worked for me in a single shot.

Comment from JEBariffic
Posted: January 25, 2013 at 3:52 pm

I’ve noticed that the image.x property is changed after using this code. For example, an image that is 400 px wide at the 0 x position will, after the code is executed on it, have its x position changed to 400, even though it does flip perfectly in place and not move to the right as the x position would imply. Its like the x position pre-execution was attached to the left side of the image, and post execution is attacked to the right. Not sure if there is a way around that (or just happening to me?)

Comment from Atlas
Posted: May 28, 2013 at 3:50 am

Thank you for taking the time to code this.

Comment from FlexMann
Posted: January 1, 2014 at 8:09 pm

Hi,
why don’t you use it in a simple way?

yourImageID.rotate = 90; // degree

Write a comment