0

I face a problem when afterUIImage rotation the white lines appear on sides of the image. In my image redactor I have rotateButton. After tapping on it I call this function:

func rotateLeft() -> UIImage? {    let radians = CGFloat.rotateRadians        // Calculate the size of the rotated image    var rotatedSize = CGRect(origin: .zero, size: size)        .applying(CGAffineTransform(rotationAngle: radians))        .integral.size    // Round the dimensions to the nearest whole number    rotatedSize.width = round(rotatedSize.width)    rotatedSize.height = round(rotatedSize.height)    // Create a context for the rotated image    UIGraphicsBeginImageContext(rotatedSize)    defer { UIGraphicsEndImageContext() }    if let context = UIGraphicsGetCurrentContext() {        // Move the origin to the center of the image        context.translateBy(x: rotatedSize.width / 2.0, y: rotatedSize.height / 2.0)                // Rotate the context        context.rotate(by: radians)                // Draw the image        draw(in: CGRect(            x: -size.width / 2.0,            y: -size.height / 2.0,            width: size.width,            height: size.height)        )                // Get the rotated image from the context        if let rotatedImage = UIGraphicsGetImageFromCurrentImageContext() {            return rotatedImage        }    }        return nil}

This function return rotated image, after what I just animate image inUIImageVIew, and in completion I assigns this new rotate image to UIImageView (everything works fine, I think).But the problem is that if I spam this button many times (button tap only work when previous rotation logic finished), the white lines become bigger and bigger.enter image description here

I read that a problem is cause of floting points after rotation, so I tried toround size, but it doesn't help.So can someone explain what Is a problem, or give me some link where I can read about this problem.

P.S. When I useUIGraphicsImageRenderer it works much slower than previous deprecated method:

func rotateLeft() -> UIImage? {    let radians = CGFloat.rotateRadians    // Calculate the size of the rotated view's containing box for our drawing space    let rotatedSize = CGSize(width: size.height, height: size.width)    // Create the renderer with the rotatedSize    let renderer = UIGraphicsImageRenderer(size: rotatedSize)    // Perform the rotation transformation within the image renderer context    let rotatedImage = renderer.image { context in        context.cgContext.translateBy(x: rotatedSize.width / 2.0, y: rotatedSize.height / 2.0)        context.cgContext.rotate(by: radians)        // Translate and rotate the graphics context        let origin = CGPoint(x: -size.width / 2, y: -size.height / 2)        // Draw the original image in the rotated context        draw(at: origin)    }    return rotatedImage}

The problem withUIGraphicsImageRenderer was that it automatically take iPhone scale(in my case 3), so image 2000x1000 became 6000x3000. You need to setup scale factor to 1, in renderer.

askedNov 7, 2023 at 18:49
Petr Bones's user avatar
1
  • Note thatUIGraphicsBeginImageContext andUIGraphicsBeginImageContextWithOptions(_:_:_:) are deprecated. You should useUIGraphicsImageRenderer instead.CommentedNov 7, 2023 at 20:34

1 Answer1

0

The CGRect functionapplying(_ t: CGAffineTransform) -> CGRect doesn't return meaningful values for rotations unless they are multiples of 90°, and even then, you might get floating point errors. Does your app support arbitrary rotation angles? If not, I would suggest either leaving the rectangle the same size for 180° rotations, or just swapping the height and width for 90° rotations.

That should preserve your image without introducing white bars on the sides, since you'll always be rendering your image into a rect with the exact number of pixels.

answeredNov 7, 2023 at 20:02
Duncan C's user avatar
Sign up to request clarification or add additional context in comments.

2 Comments

Yes, changing width to height and height to width helped, and it sounds logica since we just rotate image on 90 degree. White line isn't appear anymore. But still I don't clearly understand the problem with floating points. I tried tofloor width and height, but white lines still were there.
If you want to figure out what's going on, log the height and width before and after the rotation. I think you'll find that the numbers are changing slightly, and if one dimension changes and the other doesn't change in proportion, Core Image will leave empty space on the sides in order to preserve the aspect ratio of the image.

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.