保存到文件之前旋转图像/上下文

时间:2011-06-20 15:42:08

标签: ios rotation uiimage transform cgcontext

如何轮换上下文?

我已经尝试了CGAffineTransformRotate()CGContextRotateCTM()的所有组合,我能想到并且无法使其发挥作用。

以下代码效果很好。它以背景捕捉各种尺寸的图像,因此它们总是320x480或480x320。这很重要。但是,我希望水平图像在保存到文件之前旋转90度。

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(480, 320), NO, 0.0);
    UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 480, 320)];           
    UIImage *im = [UIImage imageWithContentsOfFile:[allImagePaths objectAtIndex:currImg]];
    iv.image = im;
    iv.backgroundColor = [UIColor blackColor];
    iv.contentMode = UIViewContentModeScaleAspectFit;               
    CGContextRef context = UIGraphicsGetCurrentContext();       
    [iv.layer renderInContext:context];
        //
        // how to rotate it around here?
        //
    UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
    NSData* imageData = UIImageJPEGRepresentation(capturedImage, 1.0);
    NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    [imageData writeToFile:[docDir stringByAppendingPathComponent:@"result.jpg"] atomically:NO]; 
    UIGraphicsEndImageContext();

每当我添加任何类型的旋转时,它都会被窃听(白色结果图像或屏幕上只有一半图像而不是旋转)。

对这个例子的任何帮助都会很好。

3 个答案:

答案 0 :(得分:2)

使用此类别方法获取灵感。这不会完全符合您的要求,但这个想法是一样的。

- (UIImage *)fixOrientation 
{   
    // No-op if the orientation is already correct
    if (self.imageOrientation == UIImageOrientationUp) return self;

    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    CGAffineTransform transform = CGAffineTransformIdentity;

    switch (self.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;

        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, self.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
    }

    switch (self.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;

        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
                                             CGImageGetBitsPerComponent(self.CGImage), 0,
                                             CGImageGetColorSpace(self.CGImage),
                                             CGImageGetBitmapInfo(self.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (self.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
            break;

        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
            break;
    }

    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}

答案 1 :(得分:1)

很难回答我自己的问题但是......

似乎主要问题是坐标系。默认情况下,使用CGContextRotateCTM()旋转会在(0,0)点附近进行旋转。意味着图像“隐藏”在视野之外。我必须做[image drawInRect:CGRectMake(0,-320,480,320)];

此外,我不得不使用2个上下文。第一个水平捕获水平图像与背景。第二个垂直保存旋转的垂直图像。

答案 2 :(得分:0)

尝试这个,尚未测试:

  CGSize size = imageIsHorizontal ? CGSizeMake(480, 320) : CGSizeMake(320, 480);
  UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
  CGContextRef context = UIGraphicsGetCurrentContext();
  CGContextRotateCTM(context, 90 * M_PI / 180);
  [image drawInRect:(CGRect){CGPointZero, size}];
  UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  NSData* imageData = UIImageJPEGRepresentation(capturedImage, 1.0);
  NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
  [imageData writeToFile:[docDir stringByAppendingPathComponent:@"result.jpg"] atomically:NO];