我需要将NSImage
旋转任意角度。对于我的应用程序的iOS版本,我从互联网上找到的几个来源一起攻击了以下解决方案:
@implementation UIImage (ut_rotate)
- (instancetype)imageRotatedByDegrees:(CGFloat)degrees{
CGFloat scale = [UIScreen mainScreen].scale; // support retina displays
float newSide = self.size.width; // square img
CGSize size = CGSizeMake(newSide, newSide);
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, newSide/2.0f, newSide/2.0f);
transform = CGAffineTransformRotate(transform, _heading * M_PI/180.0);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGContextConcatCTM(context, transform);
CGContextDrawImage(context, CGRectMake(-newSide/2.0f, -newSide/2.0f, newSide, newSide), _image.CGImage);
return [UIImage imageWithCGImage: CGBitmapContextCreateImage(context) scale:scale orientation:UIImageOrientationUp];
}
@end
请注意,此黑客支持视网膜显示。
对于Cocoa,我在其中一个互联网上找到了规范解决方案:
@implementation NSImage (ut_rotate)
- (NSImage*)imageRotatedByDegrees:(CGFloat)degrees {
// Calculate the bounds for the rotated image
// We do this by affine-transforming the bounds rectangle
NSRect imageBounds = {NSZeroPoint, [self size]};
NSBezierPath* boundsPath = [NSBezierPath bezierPathWithRect:imageBounds];
NSAffineTransform* transform = [NSAffineTransform transform];
[transform rotateByDegrees:-1.0 * degrees];// we want clockwise angles
[boundsPath transformUsingAffineTransform:transform];
NSRect rotatedBounds = {NSZeroPoint, [boundsPath bounds].size};
NSImage* rotatedImage = [[NSImage alloc] initWithSize:rotatedBounds.size] ;
// Center the image within the rotated bounds
imageBounds.origin.x = NSMidX(rotatedBounds) - (NSWidth(imageBounds) / 2);
imageBounds.origin.y = NSMidY(rotatedBounds) - (NSHeight(imageBounds) / 2);
// Start a new transform, to transform the image
transform = [NSAffineTransform transform];
// Move coordinate system to the center
// (since we want to rotate around the center)
[transform translateXBy:+(NSWidth(rotatedBounds) / 2)
yBy:+(NSHeight(rotatedBounds) / 2)];
// Do the rotation
[transform rotateByDegrees:-1.0 * degrees];
// Move coordinate system back to normal (bottom, left)
[transform translateXBy:-(NSWidth(rotatedBounds) / 2)
yBy:-(NSHeight(rotatedBounds) / 2)];
// Draw the original image, rotated, into the new image
// Note: This "drawing" is done off-screen.
[rotatedImage lockFocus];
[transform concat];
[self drawInRect:imageBounds fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0] ;
[rotatedImage unlockFocus];
return rotatedImage;
}
@end
问题是:a)结果在非视网膜显示器上看起来模糊b)不支持视网膜。
我发现在lockFocus
和unlockFocus
之间使用block-based drawing methods代替代码,但却不理解。
我正在寻找能够产生更清晰图像并支持视网膜的解决方案。根据我的需要,OS X 10.9及更高版本只支持平方源图像。
答案 0 :(得分:0)
这是完全未经测试但可能有效:
@implementation NSImage (ut_rotate)
- (NSImage*)imageRotatedByDegrees:(CGFloat)degrees {
// Calculate the bounds for the rotated image
// We do this by affine-transforming the bounds rectangle
NSRect imageBounds = {NSZeroPoint, [self size]};
NSBezierPath* boundsPath = [NSBezierPath bezierPathWithRect:imageBounds];
NSAffineTransform* transform = [NSAffineTransform transform];
[transform rotateByDegrees:-1.0 * degrees];// we want clockwise angles
[boundsPath transformUsingAffineTransform:transform];
NSRect rotatedBounds = {NSZeroPoint, [boundsPath bounds].size};
// Center the image within the rotated bounds
imageBounds.origin.x = NSMidX(rotatedBounds) - (NSWidth(imageBounds) / 2);
imageBounds.origin.y = NSMidY(rotatedBounds) - (NSHeight(imageBounds) / 2);
NSImage* rotatedImage = [NSImage imageWithSize:rotatedBounds.size flipped:NO drawingHandler:^BOOL (NSRect dstRect){
// Start a new transform, to transform the image
NSAffineTransform* transform = [NSAffineTransform transform];
// Move coordinate system to the center
// (since we want to rotate around the center)
[transform translateXBy:+(NSWidth(rotatedBounds) / 2)
yBy:+(NSHeight(rotatedBounds) / 2)];
// Do the rotation
[transform rotateByDegrees:-1.0 * degrees];
// Move coordinate system back to normal (bottom, left)
[transform translateXBy:-(NSWidth(rotatedBounds) / 2)
yBy:-(NSHeight(rotatedBounds) / 2)];
// Draw the original image, rotated, into the new image
[transform concat];
[self drawInRect:imageBounds fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
return YES;
}];
return rotatedImage;
}
@end
答案 1 :(得分:0)
我对NSImage的扩展,适用于所有学位
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);