旋转图像上下文(CGContextRotateCTM)使其变为空白。 为什么?

#define radians(degrees) (degrees * M_PI/180) UIImage *rotate(UIImage *image) { CGSize size = image.size;; UIGraphicsBeginImageContext(size); CGContextRef context = UIGraphicsGetCurrentContext(); // If this is commented out, image is returned as it is. CGContextRotateCTM (context, radians(90)); [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

其他事情可能是错的吗? 出于想法。

问题是你的上下文正在左右转angular(0,0)左右。 如果围绕左上angular旋转90度,则所有绘图都将出现在上下文的范围之外。 您需要两步转换将上下文的原点移动到中间,然后旋转。 此外,您还需要绘制以移动/旋转原点为中心的图像,如下所示:

 CGContextTranslateCTM( context, 0.5f * size.width, 0.5f * size.height ) ; CGContextRotateCTM( context, radians( 90 ) ) ; [ image drawInRect:(CGRect){ { -size.width * 0.5f, -size.height * 0.5f }, size } ] ; 

HTH

我尝试遵循代码,它的工作原理,从http://www.catamount.com/blog/1015/uiimage-extensions-for-cutting-scaling-and-rotating-uiimages/

 + (UIImage *)rotateImage:(UIImage*)src byRadian:(CGFloat)radian { // calculate the size of the rotated view's containing box for our drawing space //UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0, src.size.width, src.size.height)]; //CGAffineTransform t = CGAffineTransformMakeRotation(radian); //rotatedViewBox.transform = t; //CGSize rotatedSize = rotatedViewBox.frame.size; CGRect rect = CGRectApplyAffineTransform(CGRectMake(0,0, src.size.width, src.size.height), CGAffineTransformMakeRotation(radian)); CGSize rotatedSize = rect.size; // Create the bitmap context UIGraphicsBeginImageContext(rotatedSize); CGContextRef bitmap = UIGraphicsGetCurrentContext(); // Move the origin to the middle of the image so we will rotate and scale around the center. CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2); // // Rotate the image context CGContextRotateCTM(bitmap, radian); // Now, draw the rotated/scaled image into the context CGContextScaleCTM(bitmap, 1.0, -1.0); CGContextDrawImage(bitmap, CGRectMake(-src.size.width / 2, -src.size.height / 2, src.size.width, src.size.height), [src CGImage]); UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

如果您不想更改所有的来源和尺寸,请移动中心,然后再旋转并将中心更改为转angular,如下所示:

CGContextTranslateCTM( context, 0.5f * size.width, 0.5f * size.height ) ; CGContextRotateCTM( context, radians( 90 ) ) ; CGContextTranslateCTM( context, -0.5f * size.width, -0.5f * size.height ) ;

然后像这样正常绘制:

[image drawInRect:CGRectMake(0, 0, size.width, size.height)];

扩展Nielsbot的答案,我创build了以下片段。 请注意,这应该最好做一个function,而不是一个代码片段,以防止“复制/粘贴编程”。 我还没有得到,所以随时适应。

代码片段:

 // <Draw in frame with orientation> UIImage* imageToDrawRotated = <#image#>; float rotationAngle = <#angle#>; CGRect drawFrame = CGRectMake(<#CGFloat x#>, <#CGFloat y#>, <#CGFloat width#>, <#CGFloat height#>); CGContextTranslateCTM(UIGraphicsGetCurrentContext(), floor(drawFrame.origin.x + drawFrame.size.width/2), floor(drawFrame.origin.y + drawFrame.size.height/2)); CGContextRotateCTM(UIGraphicsGetCurrentContext(), rotationAngle); [imageToDrawRotated drawInRect:CGRectMake(-floor(drawFrame.size.width/2), -floor(drawFrame.size.height/2), drawFrame.size.width, drawFrame.size.height)]; CGContextRotateCTM(UIGraphicsGetCurrentContext(), -rotationAngle); CGContextTranslateCTM(UIGraphicsGetCurrentContext(), -floor(drawFrame.origin.x + drawFrame.size.width/2), -floor(drawFrame.origin.y + drawFrame.size.height/2)); // </Draw in frame with orientation> 

另外,我也欢迎更好的方法来将CGContext重置为之前的状态。

我喜欢@lbsweek的解决scheme,但我有点担心分配UIView只是为了转换,而是我尝试了下面

 - (UIImage *)rotateImage:(UIImage *)sourceImage byDegrees:(float)degrees { CGFloat radian = degrees * (M_PI/ 180); CGRect contextRect = CGRectMake(0, 0, sourceImage.size.width, sourceImage.size.height); float newSide = MAX([sourceImage size].width, [sourceImage size].height); CGSize newSize = CGSizeMake(newSide, newSide); UIGraphicsBeginImageContext(newSize); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGPoint contextCenter = CGPointMake(CGRectGetMidX(contextRect), CGRectGetMidY(contextRect)); CGContextTranslateCTM(ctx, contextCenter.x, contextCenter.y); CGContextRotateCTM(ctx, radian); CGContextTranslateCTM(ctx, -contextCenter.x, -contextCenter.y); [sourceImage drawInRect:contextRect]; UIImage* rotatedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return rotatedImage; }