Skip to content

Commit

Permalink
Rotate image
Browse files Browse the repository at this point in the history
  • Loading branch information
leoz committed Feb 21, 2024
1 parent f76d234 commit 92d6188
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 4 deletions.
61 changes: 61 additions & 0 deletions Sources/SwiftyCrop/Models/CropViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,47 @@ class CropViewModel: ObservableObject {
return circleCroppedImage
}

/**
Rotates the image to the angle that is rotated inside the view.
- Parameters:
- image: The UIImage to rotate
- angle: The Angle to rotate to
- Returns: A rotated UIImage if the rotating operation is successful; otherwise nil.
*/
func rotate(_ image: UIImage, _ angle: Angle) -> UIImage? {
guard let orientedImage = image.correctlyOriented else {
return nil
}

guard let cgImage = orientedImage.cgImage else {
return nil
}

let ciImage = CIImage(cgImage: cgImage)

// Prepare filter
let filter = CIFilter.straightenFilter(
image: ciImage,
radians: angle.radians
)

// Get output image
guard let output = filter?.outputImage else {
return nil
}

// Create resulting image
let context = CIContext()
guard let result = context.createCGImage(
output,
from: output.extent
) else {
return nil
}

return UIImage(cgImage: result)
}

/**
Calculates the rectangle to crop.
- Parameters:
Expand Down Expand Up @@ -178,3 +219,23 @@ private extension UIImage {
return normalizedImage
}
}

private extension CIFilter {
/**
Creates the straighten filter.
- Parameters:
- inputImage: The CIImage to use as an input image
- radians: An angle in radians
- Returns: A generated CIFilter.
*/
static func straightenFilter(image: CIImage, radians: Double) -> CIFilter? {
let angle: Double = radians != 0 ? -radians : 0
guard let filter = CIFilter(name: "CIStraightenFilter") else {
return nil
}
filter.setDefaults()
filter.setValue(image, forKey: kCIInputImageKey)
filter.setValue(angle, forKey: kCIInputAngleKey)
return filter
}
}
13 changes: 9 additions & 4 deletions Sources/SwiftyCrop/View/CropView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct CropView: View {
.onEnded { _ in
viewModel.lastOffset = viewModel.offset
}

let rotationGesture = RotationGesture()
.onChanged { value in
viewModel.angle = value
Expand Down Expand Up @@ -138,10 +138,15 @@ struct CropView: View {
}

private func cropImage() -> UIImage? {
if maskShape == .circle && configuration.cropImageCircular {
return viewModel.cropToCircle(image)
if let rotatedImage: UIImage = viewModel.rotate(image, viewModel.lastAngle) {
if maskShape == .circle && configuration.cropImageCircular {
return viewModel.cropToCircle(rotatedImage)
} else {
return viewModel.cropToSquare(rotatedImage)
}
return rotatedImage
} else {
return viewModel.cropToSquare(image)
return nil
}
}

Expand Down

0 comments on commit 92d6188

Please sign in to comment.