How can I rotate an image drawn by CGContextDrawImage()
at its center?
In drawRect:
CGContextSaveGState(c);
rect = CGRectOffset(rect, -rect.size.width / 2, -rect.size.height / 2);
CGContextRotateCTM(c, angle);
CGContextDrawImage(c, rect, doodad.CGImage);
CGContextRotateCTM(c, -angle);
CGContextTranslateCTM(c, pt.x, pt.y);
prevRect = rect;
CGContextRestoreGState(c);
I draw the image at the origin, and rotate it at its center, then translate to where it should be drawn. Not working.
This function can draw image on an existing image with rotation angle in radians.
Swift 3:
If you need to create and empty image with size and color, use:
You can use the following method for rotating image.
If you use angle, then here is the macro for converting degree to radian
The thing to remember about coordinate transformations—well, one of the things to remember—is that you are not manipulating objects, like the Transform command in a graphics editor; you are manipulating space itself.
Imagine that the device is suspended over a desk by a gooseneck arm, and is fixed in position. Coordinate transformations move the desk around (translation), and turn it one way or the other (rotation), and even squash and stretch it (scaling).
Another of the things to remember about coordinate transformations is that transformation is always relative to the origin. Imagine that your desk starts out with one of its corners—corresponding to a corner of your view—directly underneath the corner of where your view ends up on the screen. Translating moves the corner of the desk, and the rest of the desk with it, sliding it one way or another underneath the screen. Rotating turns the desk around that corner.
One more thing: Transformations affect the future, not the past. Drawing something and then trying to transform it won't work, because you don't transform what you've drawn, you transform the space you're going to draw into. So, we need to move the desk before we can place the image in the right spot.
(I mention that last part because you have a couple of transformation commands that are immediately reverted by your
CGContextRestoreGState
call. There is no drawing in between for them to affect.)So, let's start with the unrotated rectangle of the image.
Now,
CGContextDrawImage
takes a rectangle, but, as you know, it's going to draw the image from the lower-left corner of that rectangle, not the center. (Hence this whole exercise.)So, here's what you're going to do. At the end of this, you're going to draw the image not at that point shown above, but at the zero point—that is, on the very corner of the desk. (Not centered on the corner, but with the image's corner on the desk's corner.)
How will that work? It takes some set-up. You're going to have to move your desk.
First, you need to move your desk up and right until the origin corner of your desk is at the desired center point:
Then you do the rotation (turning the desk around its origin corner):
Then you move the desk back down and left by half of the image's width and height:
And then, finally, place the image on the corner of the desk.
With your desk so moved, the center of that rectangle lies directly under the point on the screen where you want the image centered, so the image is so centered.
If you're ultimately drawing to the screen (as opposed to generating an image to save to a file), you might consider not using a CGContext at all, but rather putting the image into a CALayer and rotating the layer about its anchor point:
If the image is itself generated (as opposed to a static resource from your bundle or something user-supplied), you might consider making it out of layers and setting the
sublayerTransform
of their parent/common-ancestor layer:(There may be ways to do this with views instead of layers; I'm a Mac guy, so I don't know UIView very deeply.)