I am working on iOS SwiftUI app Image editor, for image cropping I used the Mantis library but I faced one problem , when I pick image from gallery its working perfectly but getting app crashed when image is picked through camera .Getting this error "Message from debugger: Terminated due to memory issue"
Mantis library install link through package manager
Other library I found is QCropper but it does not have any documentation for SwiftUI
My Code : HomePage
import SwiftUI
import Mantis
struct HomePage: View {
@State var bgImage :UIImage?
@State var camIsClicked = false
@State private var isImagePickerDisplay = false
@State var sourceType: UIImagePickerController.SourceType?
@State var showCropper = false
@State var gotoImageEdit = false
@State private var cropShapeType: Mantis.CropShapeType = .rect
@State private var presetFixedRatioType: Mantis.PresetFixedRatioType = .canUseMultiplePresetFixedRatio()
var camAlertView:some View{
VStack {
VStack{
VStack(spacing:Constants.device == .pad ? 20:10){
Text("Select One!")
.foregroundColor(Color.red)
.fontWeight(.bold)
.font(Constants.device == .pad ? .largeTitle:.title2)
Divider()
.frame(width:Constants.width*0.65 , height:Constants.device == .pad ? 3.5:2)
.background(Color.red)
}
.padding(.top)
Spacer()
Button {
sourceType = .photoLibrary
isImagePickerDisplay.toggle()
} label: {
Text("Gallery")
.fontWeight(.bold)
.font(Constants.device == .pad ? .title:.title3)
.frame(width:Constants.width*0.34, height:Constants.device == .pad ? 70:40)
.background(Color.red)
.cornerRadius(Constants.device == .pad ? 35:20)
}
Spacer()
Button {
sourceType = .camera
isImagePickerDisplay.toggle()
} label: {
Text("Camera")
.fontWeight(.bold)
.font(Constants.device == .pad ? .title:.title3)
.frame(width:Constants.width*0.34, height:Constants.device == .pad ? 70:40)
.background(Color.red)
.cornerRadius(Constants.device == .pad ? 35:20)
}
Spacer()
}
.frame(width:Constants.width*0.65, height:Constants.height*0.39)
.background(Color.white)
.cornerRadius(20)
.foregroundColor(.white)
}
.frame(width:Constants.width, height:Constants.height)
.background(Color.black
.opacity(0.8)
.ignoresSafeArea()
.onTapGesture {
camIsClicked = false
})
}
var body: some View {
ZStack{
NavigationLink( destination: ImageEditPage(bgImage: $bgImage),isActive: $gotoImageEdit) {
EmptyView()
}
VStack{
Button {
camIsClicked.toggle()
} label: {
Text("Pick Image")
.padding()
.background(Color.green)
.cornerRadius(30)
}
}
if camIsClicked{
camAlertView
}
if isImagePickerDisplay{
if sourceType == .photoLibrary{
SUImagePickerView(sourceType: .photoLibrary, image: $bgImage, isPresented: $isImagePickerDisplay, camIsClicked: $camIsClicked, bgImageIsSelected: $showCropper)
}else{
SUImagePickerView(sourceType: .camera, image: $bgImage, isPresented: $isImagePickerDisplay, camIsClicked: $camIsClicked, bgImageIsSelected: $showCropper)
}
}
}
.navigationBarHidden(true)
.fullScreenCover(isPresented: $showCropper, content: {
ImageCropper(gotoImageEdit: $gotoImageEdit, image: $bgImage,cropShapeType: $cropShapeType,presetFixedRatioType: $presetFixedRatioType)
.ignoresSafeArea()
})
}
}
struct HomePage_Previews: PreviewProvider {
static var previews: some View {
HomePage()
}
}
ImageCropper Class
import SwiftUI
import Mantis
struct ImageCropper: UIViewControllerRepresentable {
@Binding var gotoImageEdit : Bool
@Binding var image: UIImage?
@Binding var cropShapeType: Mantis.CropShapeType
@Binding var presetFixedRatioType: Mantis.PresetFixedRatioType
@Environment(\.presentationMode) var presentationMode
class Coordinator: CropViewControllerDelegate {
func cropViewControllerDidImageTransformed(_ cropViewController: CropViewController) {
}
var parent: ImageCropper
init(_ parent: ImageCropper) {
self.parent = parent
}
func cropViewControllerDidCrop(_ cropViewController: CropViewController, cropped: UIImage, transformation: Transformation, cropInfo: CropInfo) {
parent.image = cropped
print("transformation is \(transformation)")
parent.gotoImageEdit = true
parent.presentationMode.wrappedValue.dismiss()
}
func cropViewControllerDidCancel(_ cropViewController: CropViewController, original: UIImage) {
parent.presentationMode.wrappedValue.dismiss()
}
func cropViewControllerDidFailToCrop(_ cropViewController: CropViewController, original: UIImage) {
}
func cropViewControllerDidBeginResize(_ cropViewController: CropViewController) {
}
func cropViewControllerDidEndResize(_ cropViewController: CropViewController, original: UIImage, cropInfo: CropInfo) {
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> CropViewController {
var config = Mantis.Config()
config.cropViewConfig.cropShapeType = cropShapeType
config.presetFixedRatioType = presetFixedRatioType
let cropViewController = Mantis.cropViewController(image: image!,
config: config)
cropViewController.delegate = context.coordinator
return cropViewController
}
func updateUIViewController(_ uiViewController: CropViewController, context: Context) {
}
}
I think it is a bug in the last version of the mantis library. I had the same problem. I installed version 2.1.2 and it seems to work. Your code looks fine.