'Flip image vertically (Swift)

How to flip an UIImage vertically (up/down)? This is a question that is asked before...

I am showing an image in a image view and it is possible to draw in the image. For the erase function I use an UIBezierpath in a CAShapeLayer. The strokeColor of the CAShapeLayer is UIColor(patternImage: background).cgColor, where background is the same image as the image in the image view. The background turned out to be upside down. From other Stackoverflow posts I understand that this is caused because UIKit and Core Graphics use another origin for their coordinates system.

I tried some of the solutions in the Stackoverflow posts to flip my background image. None of these where working:

UIImage* sourceImage = [UIImage imageNamed:@"whatever.png"];
UIImage* flippedImage = [UIImage imageWithCGImage:sourceImage.CGImage 
                                            scale:sourceImage.scale
                                      orientation:UIImageOrientationUpMirrored];

let ciimage: CIImage = CIImage(CGImage: imagenInicial.CGImage!)
let rotada3 = ciimage.imageByApplyingTransform(CGAffineTransformMakeScale(1, -1))

func flipImageVertically() -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(size, false, scale)
    let bitmap = UIGraphicsGetCurrentContext()!

    bitmap.translateBy(x: size.width / 2, y: size.height / 2)
    bitmap.scaleBy(x: 1.0, y: -1.0)

    bitmap.translateBy(x: -size.width / 2, y: -size.height / 2)
    bitmap.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))

    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return image
}

I started experimenting with the last solution by changing the scale and just watching the result. It turned out that my solution was that I needed to use

bitmap.scaleBy(x: 1.0, y: 1.0)

in the function flipImageVertically() to create a new upside down image.

I don't understand this. By scaling with 1 I thought I was not changing anything. I don't know if the imageOrientation of my original image is important. But the imageOrientation is .up.

I hope someone can explain why I can flip an image vertically with the function

func flipImageVertically() -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(size, false, scale)
    let bitmap = UIGraphicsGetCurrentContext()!

    bitmap.translateBy(x: size.width / 2, y: size.height / 2)
    bitmap.scaleBy(x: 1.0, y: 1.0)

    bitmap.translateBy(x: -size.width / 2, y: -size.height / 2)
    bitmap.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))

    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return image
}


Solution 1:[1]

I think that the point is that you are getting the context with UIGraphicsGetCurrentContext() and then drawing using the draw(_:CGImage, in: CGRect) function.

In fact you can safely delete these lines in your code because they do exactly nothing:

bitmap.translateBy(x: size.width / 2, y: size.height / 2)
bitmap.scaleBy(x: 1.0, y: 1.0)
bitmap.translateBy(x: -size.width / 2, y: -size.height / 2)

I mean... you are scaling by 1.0 (which is doing nothing), and you are translating the context by the same amount in opposite directions which means you are not translating at all.

If you instead draw to the context using the UIImage instance method draw(in: CGRect), the image is not flipped.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 kaharoth