2009-07-16 10 views
28

J'ai un UIView que j'essaye de rendre dans un UIImage en utilisant [CALayer renderInContext:]. Cependant, je trouve que l'image résultante est retournée verticalement. Je m'attends à cela en raison des différents systèmes de coordonnées. Cependant, retour à la normale avec un affines je puis essayer de retourner le contexte transformer - mais il n'a pas de effet:Flip vertical de 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); 

Qu'est-ce que je fais mal?

Répondre

26

Le CTM affecte le dessin ultérieur; vous capturez ce que vous avez déjà dessiné. Vous devez concaténer cette transformation avant de dessiner, pas après.

29

Voici un code que j'ai écrit à partir de cette réponse, dans le cas où il est utile à tout le monde:

#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

Voici le même code que ci-dessus (la réponse de benvolioT) mais dans 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 
} 

Et voici une meilleure façon de SWIFT:

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

J'utilise ce code dans rapide:

  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()