Вопрос по uikit, core-graphics, iphone – Вертикальный переворот CGContext

32

У меня есть 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);

Что я делаю неправильно?

Ваш Ответ

6   ответов
0

Используйте эту функцию в Swift 4:

func drawImage(image: UIImage) -> UIImage {
    // Setup our context
    let opaque = false
    let scale: CGFloat = 0 // 0 means we use scale factor of the device’s main screen.
    UIGraphicsBeginImageContextWithOptions(image.size, opaque, scale)
    let context = UIGraphicsGetCurrentContext()!
    let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: image.size.height)
    context.concatenate(flipVertical) // flip by y

    // draw your another figures
    //...
    // Drawing complete, set context to image and finish
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image!
}
6

Здесь тот же код, что и выше (ответ benvolioT), но в SWIFT 4.0

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

    let tempImageView:UIImageView = UIImageView(image: originalImage)
    UIGraphicsBeginImageContext(tempImageView.frame.size)
    let context:CGContext = UIGraphicsGetCurrentContext()!
    let flipVertical: CGAffineTransform = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: tempImageView.frame.size.height)

    context.concatenate(flipVertical)
    tempImageView.layer.render(in: 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
}
Второй метод не устраняет проблему, о которой говорится в Вопросе, но первый
32

Вот код, который я написал на основе этого ответа, на случай, если он кому-нибудь пригодится:

#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;
}   
1

Я использую этот код в Swift:

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

Свифт 4:

let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: originalImage.size.height)
ctx.concatenate(flipVertical)
29

CTM влияет на будущее рисование; Вы захватываете то, что уже нарисовали. Вы должны согласовать это преобразование до того, как начнете рисовать, а не после.

Похожие вопросы