iOS Picture Rotation Method

Keywords: iOS

iOS Picture Rotation Method

Rotate specific angles through CGImage or CIImage

UI Image can be initialized by CGImage or CIImage by init (cgImage: CGImage, scale: CGFloat, orientation: UI Image Orientation) and init (ciImage: CIImage, scale: CGFloat, orientation: UI Image Orientation). Through different values of UI Image Orientation, the image can be rotated 90, 180, 270 degrees.

Drawing with original drawing

Arbitrary angle of rotating picture is realized by drawing original picture. You can draw the red background first. The effect is as follows.

static func rotateImage(_ image: UIImage, withAngle angle: Double) -> UIImage? {
    if angle.truncatingRemainder(dividingBy: 360) == 0 { return image }
    
    let imageRect = CGRect(origin: .zero, size: image.size)
    let radian = CGFloat(angle / 180 * M_PI)
    let rotatedTransform = CGAffineTransform.identity.rotated(by: radian)
    var rotatedRect = imageRect.applying(rotatedTransform)
    rotatedRect.origin.x = 0
    rotatedRect.origin.y = 0
    
    UIGraphicsBeginImageContext(rotatedRect.size)
    guard let context = UIGraphicsGetCurrentContext() else { return nil }
    context.translateBy(x: rotatedRect.width / 2, y: rotatedRect.height / 2)
    context.rotate(by: radian)
    context.translateBy(x: -image.size.width / 2, y: -image.size.height / 2)
    image.draw(at: .zero)
    let rotatedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return rotatedImage
}

If the rotation angle can be divided by 360, no rotation is needed and the original image is returned directly. If it is from other angles, it needs to be drawn.

The CGRect whose origin is zero and the size is the size of the original image is obtained first, and is represented by imageRect. CGAffineTransform.identity obtains the identity matrix. CGAffineTransform rotated (by angle: CGFloat) - > CGAffineTransform method rotates the matrix to a certain angle and returns the rotated matrix. The angle is in the radian system. The positive value is counterclockwise and the negative value is clockwise. CGRect's application (t: CGAffine Transform) - > CGRect method uses the rotated matrix for imageRect, returns the minimum CGRect containing imageRect's rotation, and uses rotatedRect as the bitmap size. The origin of rotatedRect may not be zero and needs to be set to zero.

The CGContext of the bitmap rotates on the axis of the origin. To rotate the picture on the center axis, first move the origin of CGContext to the center context.translateBy(x: rotatedRect.width / 2, y: rotatedRect.height / 2), and then rotate context.rotate(by: radian). The rotate(by angle: CGFloat) method of CGContext is also based on radian system. The positive value indicates that the context rotates counter-clockwise. The effect of drawing is that the picture rotates clockwise. At this point, the origin of context is in the center of the bitmap, which needs to be displaced according to half of the size of the original image. context.translateBy(x: -image.size.width / 2, y: -image.size.height / 2), the center of the whole picture drawn from the origin is in the center of the bitmap area.

If you want to get a red background, fill in the red immediately after you get the context, that is, add guard let context = UIGraphics GetCurrentContext () else {return nil}.

UIColor.red.setFill()
context.fill(rotatedRect)

Drawing by CALayer

You can put the picture on the UIView and use CALayer to draw the rotated picture.

static func rotateImage(_ image: UIImage, withAngle angle: Double) -> UIImage? {
    if angle.truncatingRemainder(dividingBy: 360) == 0 { return image }
    
    let imageView = UIImageView(image: image)
    imageView.transform = CGAffineTransform.identity.rotated(by: CGFloat(angle / 180 * M_PI))
    let rotatedRect = imageView.bounds.applying(imageView.transform)
    let containerView = UIView(frame: CGRect(origin: .zero, size: rotatedRect.size))
    imageView.center = containerView.center
    containerView.addSubview(imageView)
    
    UIGraphicsBeginImageContext(containerView.bounds.size)
    guard let context = UIGraphicsGetCurrentContext() else { return nil }
    containerView.layer.render(in: context)
    let rotatedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return rotatedImage
}

Place the original image in UI Image View, represent it with image View, and then rotate the matrix. Get the rotated CGRect and create a UIView of the same size, which is represented as the parent view of the imageView in ContainerView. Place the imageView in the middle. Draw with the layer of containerView.

To get a red background, set the background color after creating the containerView, that is, add the background color after let containerView = UIView (frame: CGRect (origin:.Zero, size: rotatedRect. size)

containerView.backgroundColor = .red

For reprinting, please indicate the source: http://www.cnblogs.com/silence-cnblogs/p/6496564.html

Posted by gprobst on Wed, 10 Apr 2019 18:00:31 -0700