Skip to content

Instantly share code, notes, and snippets.

@samsonjs
Forked from alwerr/crop.swift
Created April 26, 2023 18:52
Show Gist options
  • Save samsonjs/455866ce3989ceadb144ff1e9da5bff4 to your computer and use it in GitHub Desktop.
Save samsonjs/455866ce3989ceadb144ff1e9da5bff4 to your computer and use it in GitHub Desktop.
struct ContentViews: View {
@State var image: UIImage
@State private var imageWidth: CGFloat = 0
@State private var imageHeight: CGFloat = 0
@State private var imageFrame: CGRect = .zero
@State private var rotationAngle: Double = 0
@State private var wdt: Double = 0
@State private var hgt: Double = 0
@State private var cropRect = CGRect(x: 0, y: 0, width: 200, height: 200)
var body: some View {
VStack {
Button(action: {
withAnimation {
self.cropRect.size.width = 200
self.cropRect.size.height = 200
}
}) {
Text("scale")
}
Button(action: {
withAnimation {
rotationAngle += 90
}
}) {
Text("Rotate")
}
// The actual crop function
//bug: the crop area is wrong
Button(action: {
let imageFrame = self.imageFrame
let cropRect = self.cropRect
let imageToViewScale = image.size.width / imageFrame.width
let rect = CGRect(
x: imageToViewScale * cropRect.origin.x,
y: imageToViewScale * cropRect.origin.y,
width: imageToViewScale * cropRect.width,
height: imageToViewScale * cropRect.height
)
if let croppedImage = image.cgImage?.cropping(to: rect) {
let uiImage = UIImage(cgImage: croppedImage)
NSLog("Cropped image: \(uiImage)")
} else {
NSLog("Failed to crop \(rect) from image")
}
}) {
Text("Crop")
}
ZStack {
GeometryReader { geo in
Image(uiImage: image)
.resizable()
.scaledToFit()
.clipped()
.rotationEffect(.degrees(rotationAngle))
Rectangle()
.stroke(Color.white, lineWidth: 2)
.background(Color.black.opacity(0.8))
.position(x: self.cropRect.midX, y: self.cropRect.midY)
.frame(width: cropRect.size.width, height: cropRect.size.height)
//bug: if we rotate the image the rectangle is out of bounds
.rotationEffect(.degrees(rotationAngle))
.gesture(
DragGesture()
// bug: the rectngle can move outside the image
.onChanged { value in
let x = value.location.x - (self.cropRect.width / 2)
let y = value.location.y - (self.cropRect.height / 2)
let maxX = geo.size.width - self.cropRect.width
let maxY = geo.size.height - self.cropRect.height
self.cropRect.origin.x = min(max(x, 0), maxX)
self.cropRect.origin.y = min(max(y, 0), maxY)
imageFrame = geo.frame(in: .local)
}
).onAppear {
wdt = geo.size.width
hgt = geo.size.height
cropRect = CGRect(x: 0, y: 0, width: 200, height: 200)
imageFrame = geo.frame(in: .local)
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment