aboutsummaryrefslogtreecommitdiff
path: root/Sources
diff options
context:
space:
mode:
Diffstat (limited to 'Sources')
-rw-r--r--Sources/SwiftyCrop/Models/CropViewModel.swift61
-rw-r--r--Sources/SwiftyCrop/View/CropView.swift13
2 files changed, 70 insertions, 4 deletions
diff --git a/Sources/SwiftyCrop/Models/CropViewModel.swift b/Sources/SwiftyCrop/Models/CropViewModel.swift
index a9557ac..9d5e16d 100644
--- a/Sources/SwiftyCrop/Models/CropViewModel.swift
+++ b/Sources/SwiftyCrop/Models/CropViewModel.swift
@@ -123,6 +123,47 @@ class CropViewModel: ObservableObject {
}
/**
+ 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:
- image: The UIImage to calculate the rectangle to crop for
@@ -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
+ }
+}
diff --git a/Sources/SwiftyCrop/View/CropView.swift b/Sources/SwiftyCrop/View/CropView.swift
index c76f7f8..9619efb 100644
--- a/Sources/SwiftyCrop/View/CropView.swift
+++ b/Sources/SwiftyCrop/View/CropView.swift
@@ -64,7 +64,7 @@ struct CropView: View {
.onEnded { _ in
viewModel.lastOffset = viewModel.offset
}
-
+
let rotationGesture = RotationGesture()
.onChanged { value in
viewModel.angle = value
@@ -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
}
}