Rotate an image (was Re: Transform and NSImageView)
Rotate an image (was Re: Transform and NSImageView)
- Subject: Rotate an image (was Re: Transform and NSImageView)
- From: Annard Brouwer <email@hidden>
- Date: Fri, 2 Dec 2005 10:58:42 +0100
Hi David,
This problem was bugging me too. Based on some code that I found on
the old archives I came up with the following method that works
nicely. I'll copy it here verbatim because I had a hard time finding
a good solution so now others don't have to. Criticism welcome of
course.
Regarding the disappearing image: one of the things you have to
remember is to reposition the image properly, because it will move in
space after the rotation.
static inline double rad(int alpha)
{
return ((alpha * pi)/180);
}
- (NSImage *)rotatedImage:(NSImage *)image
angle:(int)alpha
{
float factorW, factorH, dW, dH;
NSAffineTransform *centreOp, *rotateOp;
NSImage *tmpImage;
NSPoint startPoint;
NSGraphicsContext* graphicsContext;
BOOL wasAntialiasing;
NSImageInterpolation previousImageInterpolation;
if (0 == alpha)
return image;
factorW = fabs(cos(rad(alpha)));
factorH = fabs(sin(rad(alpha)));
dW = [image size].width * factorW + [image size].height * factorH;
dH = [image size].width * factorH + [image size].height * factorW;
tmpImage = [[NSImage alloc] initWithSize: NSMakeSize(dW, dH)];
centreOp = [NSAffineTransform transform];
[centreOp translateXBy: dW / 2 yBy: dH / 2];
rotateOp = [NSAffineTransform transform];
[rotateOp rotateByDegrees: alpha];
[rotateOp appendTransform: centreOp];
[image setMatchesOnMultipleResolution: NO];
[image setUsesEPSOnResolutionMismatch: YES];
[tmpImage lockFocus];
graphicsContext = [NSGraphicsContext currentContext];
wasAntialiasing = [graphicsContext shouldAntialias];
previousImageInterpolation = [graphicsContext imageInterpolation];
[graphicsContext setShouldAntialias: YES];
[graphicsContext setImageInterpolation: NSImageInterpolationHigh];
[rotateOp concat];
startPoint = NSMakePoint(-[image size].width / 2, -[image
size].height / 2);
[image drawAtPoint: startPoint
fromRect: NSMakeRect(0, 0, [image size].width, [image
size].height)
operation: NSCompositeCopy
fraction: 1.0];
[graphicsContext setShouldAntialias: wasAntialiasing];
[graphicsContext setImageInterpolation:
previousImageInterpolation];
[tmpImage unlockFocus];
[tmpImage setDataRetained: YES];
[tmpImage setScalesWhenResized: YES];
return [tmpImage autorelease];
}
This allows for high-res rotation, you could optimise it by removing
all the stuff related to the graphicsContext.
Good luck,
Annard
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden