0

I would like to allow a user to crop images by drawing a closed shape on the original image. Sort of like Snapchat stickers. I was looking at this post from 2012 and was curious if there is an updated way to do this with SwiftUI.

To clarify, I would like to take user input (drawing) over a displayed image and crop the actual image (not the view) with a mask that is that shape.

Dante
  • 31
  • 5

1 Answers1

4

Actually your question need to more specific.

but you can resize your image by following code in swift ui.

Image("Your Image name here!")
    .resizable()
    .frame(width: 300, height: 300)
    

if you want to crop at any position of the image you may try this one

import SwiftUI

struct ContentView: View {
    var body: some View {
        
        CropImage(imageName: "Your Image name here!")
        
    }
}

// struct Shape
struct CropFrame: Shape {
    let isActive: Bool
    func path(in rect: CGRect) -> Path {
        guard isActive else { return Path(rect) } // full rect for non active
        
        let size = CGSize(width: UIScreen.main.bounds.size.width*0.7, height: UIScreen.main.bounds.size.height/5)
        let origin = CGPoint(x: rect.midX - size.width/2, y: rect.midY - size.height/2)
        return Path(CGRect(origin: origin, size: size).integral)
    }
}

// struct image crop
struct CropImage: View {
    
    let imageName: String
    
    @State private var currentPosition: CGSize = .zero
    @State private var newPosition: CGSize = .zero
    @State private var clipped = false
    
    var body: some View {
        
        VStack {
            
            ZStack {
                
                Image(imageName)
                    .resizable()
                    .scaledToFit()
                    .offset(x: currentPosition.width, y: currentPosition.height)
                
                Rectangle()
                    .fill(Color.black.opacity(0.3))
                    .frame(width: UIScreen.main.bounds.size.width*0.7 , height: UIScreen.main.bounds.size.height/5)
                    .overlay(Rectangle().stroke(Color.white, lineWidth: 3))
            }
            .clipShape(
                CropFrame(isActive: clipped)
            )
            .gesture(DragGesture()
                        .onChanged { value in
                            currentPosition = CGSize(width: value.translation.width + newPosition.width, height: value.translation.height + newPosition.height)
                        }
                        .onEnded { value in
                            currentPosition = CGSize(width: value.translation.width + newPosition.width, height: value.translation.height + newPosition.height)
                            
                            newPosition = currentPosition
                        })
            
            
            Button (action : { clipped.toggle() }) {
                
                Text("Crop Image")
                    .padding(.all, 10)
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .shadow(color: .gray, radius: 1)
                    .padding(.top, 50)
                
            }
        }
    }
}

This is the full code of a view with image cropping.

else you may use a library from GitHub, see the GitHub demo here

ios coder
  • 1
  • 4
  • 31
  • 91
Al Mustakim
  • 480
  • 4
  • 11
  • I’m not sure about this code. It still seems to me that you are modifying the view instead of the image itself. I’ll check out the GitHub it looks promising. – Dante Mar 25 '21 at 04:16
  • The old SO post might be a better explanation of what I mean. – Dante Mar 25 '21 at 04:16
  • then you can use the library , check the GitHub url and see the documentation . maybe you will able to find your solution. enjoy ! – Al Mustakim Mar 25 '21 at 04:21
  • if the code work for you don't forget to accept answer . it will help others to found proper solution. – Al Mustakim Mar 25 '21 at 05:39