Ответ 1
CTM влияет на будущий рисунок; вы захватываете то, что вы уже нарисовали. Вам нужно выполнить эту трансформацию, прежде чем рисовать, а не после.
У меня есть UIView, который я пытаюсь сделать в UIImage, используя [CALayer renderInContext:]. Однако я обнаружил, что результирующее изображение перевернуто вертикально. Я как бы ожидаю этого из-за разных систем координат. Тем не менее, я затем пытаюсь перевернуть контекст обратно к нормальному с аффинным преобразованием - но это не имеет никакого эффекта:
CGAffineTransform flipVertical = CGAffineTransformMake(
1, 0, 0, -1, 0, imageContextHeight
);
CGContextConcatCTM(imageContext, flipVertical);
CGImageRef cgImage = CGBitmapContextCreateImage(imageContext);
UIImage* uiImage = [[UIImage imageWithCGImage:cgImage] retain];
CGImageRelease(cgImage);
Что я делаю неправильно?
CTM влияет на будущий рисунок; вы захватываете то, что вы уже нарисовали. Вам нужно выполнить эту трансформацию, прежде чем рисовать, а не после.
Вот какой код, который я написал на основе этого ответа, в случае, если он кому-то полезен:
#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;
}
Вот тот же код, что и выше (ответ benvolioT), но в 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
}
И вот еще лучший способ в SWIFT:
func flipImageVertically(originalImage:UIImage) -> UIImage {
let image:UIImage = UIImage(CGImage: originalImage.CGImage, scale: 1.0, orientation: UIImageOrientation.RightMirrored)!
return image
}
Я использую этот код быстрым:
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()