2009-07-16 9 views
28

Tôi có UIView mà tôi đang cố gắng kết xuất thành UIImage bằng [CALayer renderInContext:]. Tuy nhiên, tôi thấy rằng hình ảnh kết quả được lật theo chiều dọc. Tôi mong đợi điều này do các hệ thống tọa độ khác nhau. Tuy nhiên, sau đó tôi thử và lật ngữ cảnh trở lại bình thường bằng biến đổi affine - nhưng nó không có bất kỳ ảnh hưởng nào:Lật dọc CGContext

CGAffineTransform flipVertical = CGAffineTransformMake(
    1, 0, 0, -1, 0, imageContextHeight 
); 
CGContextConcatCTM(imageContext, flipVertical); 
CGImageRef cgImage = CGBitmapContextCreateImage(imageContext); 
UIImage* uiImage = [[UIImage imageWithCGImage:cgImage] retain]; 
CGImageRelease(cgImage); 

Tôi làm gì sai?

Trả lời

26

CTM ảnh hưởng đến bản vẽ trong tương lai; bạn đang chụp những gì bạn đã vẽ. Bạn cần phải concat rằng chuyển đổi trước khi bạn vẽ, không phải sau.

29

Dưới đây là một số mã mà tôi viết dựa trên câu trả lời này, trong trường hợp nó là hữu ích cho bất cứ ai:

#import <QuartzCore/QuartzCore.h> 
... 
+ (UIImage *) flipImageVertically:(UIImage *)originalImage { 
    UIImageView *tempImageView = [[UIImageView alloc] initWithImage:originalImage]; 

    UIGraphicsBeginImageContext(tempImageView.frame.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGAffineTransform flipVertical = CGAffineTransformMake(
      1, 0, 0, -1, 0, tempImageView.frame.size.height 
    ); 
    CGContextConcatCTM(context, flipVertical); 

    [tempImageView.layer renderInContext:context]; 

    UIImage *flipedImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    [tempImageView release]; 

    return flipedImage; 
} 
4

Đây là đoạn mã tương tự như trên (benvolioT của câu trả lời) nhưng trong SWIFT

import QuartzCore 
... 
func flipImageVertically(originalImage:UIImage) -> UIImage{ 

    let tempImageView:UIImageView = UIImageView(image: originalImage) 
    UIGraphicsBeginImageContext(tempImageView.frame.size) 
    let context:CGContextRef = UIGraphicsGetCurrentContext() 
    let flipVertical:CGAffineTransform = CGAffineTransformMake(1,0,0,-1,0,tempImageView.frame.size.height) 
    CGContextConcatCTM(context, flipVertical) 
    tempImageView.layer .renderInContext(context) 

    let flippedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    return flippedImage 
} 

Và đây là một cách tốt hơn trong SWIFT:

func flipImageVertically(originalImage:UIImage) -> UIImage { 
    let image:UIImage = UIImage(CGImage: originalImage.CGImage, scale: 1.0, orientation: UIImageOrientation.RightMirrored)! 
    return image 
} 
1

tôi sử dụng mã này trong nhanh chóng:

  UIGraphicsBeginImageContextWithOptions(myImageView.image!.size, false, 1.0) 

      var context = UIGraphicsGetCurrentContext() 

      //move and invert canvas by scaling 
      CGContextTranslateCTM(context, myImageView.image!.size.width, 0) 
      CGContextScaleCTM(context, -1, 1) 

      myImageView.image!.drawInRect(CGRect(x: 0, y: 0, width: myImageView.image!.size.width, height: myImageView.image!.size.height)) 

      // move back and reinvert 
      CGContextScaleCTM(context, 1, 1) 
      CGContextTranslateCTM(context, -myImageView.image!.size.width, 0) 

      let flippedImg = UIGraphicsGetImageFromCurrentImageContext() 

      myImageView.image = flippedImg 

      UIGraphicsEndImageContext()