fix(imagepicker): 크롭 범위를 보정한다

This commit is contained in:
Yu Sung
2026-08-03 21:13:45 +09:00
parent 9320657bac
commit 2db4ef1c35
6 changed files with 442 additions and 15 deletions

View File

@@ -0,0 +1,15 @@
import CoreGraphics
enum ImageCropGeometry {
static func maximumCropSize(fitting imageSize: CGSize, aspectRatio: CGFloat) -> CGSize {
guard imageSize.width > 0, imageSize.height > 0, aspectRatio > 0 else {
return .zero
}
if imageSize.width / imageSize.height > aspectRatio {
return CGSize(width: imageSize.height * aspectRatio, height: imageSize.height)
}
return CGSize(width: imageSize.width, height: imageSize.width / aspectRatio)
}
}

View File

@@ -274,27 +274,35 @@ struct ImageCropEditorView: View {
private func cropSize(in canvas: CGSize) -> CGSize {
switch aspectPolicy {
case .square:
let side = max(120, min(canvas.width, canvas.height) * 0.72)
return CGSize(width: side, height: side)
let fittedSize = fittedImageSize(imageSize: normalizedImage.size, canvasSize: canvas)
return ImageCropGeometry.maximumCropSize(fitting: fittedSize, aspectRatio: 1)
case .free:
if freeCropSize == .zero {
return defaultFreeCropSize(in: canvas)
}
let minCropSize: CGFloat = 120
let maxCropWidth = max(minCropSize, canvas.width - 24)
let maxCropHeight = max(minCropSize, canvas.height - 24)
let fittedSize = fittedImageSize(imageSize: normalizedImage.size, canvasSize: canvas)
let maxCropWidth = fittedSize.width
let maxCropHeight = fittedSize.height
let minCropWidth = min(120, maxCropWidth)
let minCropHeight = min(120, maxCropHeight)
return CGSize(
width: freeCropSize.width.clamped(min: minCropSize, max: maxCropWidth),
height: freeCropSize.height.clamped(min: minCropSize, max: maxCropHeight)
width: freeCropSize.width.clamped(min: minCropWidth, max: maxCropWidth),
height: freeCropSize.height.clamped(min: minCropHeight, max: maxCropHeight)
)
}
}
private func defaultFreeCropSize(in canvas: CGSize) -> CGSize {
let width = max(120, min(canvas.width * 0.82, canvas.width - 24))
let height = max(120, min(canvas.height * 0.58, canvas.height - 24))
return CGSize(width: width, height: height)
let preferredSize = CGSize(
width: max(120, min(canvas.width * 0.82, canvas.width - 24)),
height: max(120, min(canvas.height * 0.58, canvas.height - 24))
)
let fittedSize = fittedImageSize(imageSize: normalizedImage.size, canvasSize: canvas)
return ImageCropGeometry.maximumCropSize(
fitting: fittedSize,
aspectRatio: preferredSize.width / preferredSize.height
)
}
private func handlePosition(handle: CropHandle, cropSize: CGSize, canvasSize: CGSize) -> CGPoint {
@@ -318,14 +326,16 @@ struct ImageCropEditorView: View {
lastFreeCropSize = currentCropSize
}
let minCropSize: CGFloat = 120
let maxCropWidth = max(minCropSize, canvasSize.width - 24)
let maxCropHeight = max(minCropSize, canvasSize.height - 24)
let fittedSize = fittedImageSize(imageSize: normalizedImage.size, canvasSize: canvasSize)
let maxCropWidth = fittedSize.width
let maxCropHeight = fittedSize.height
let minCropWidth = min(120, maxCropWidth)
let minCropHeight = min(120, maxCropHeight)
let width = (lastFreeCropSize.width + (translation.width * handle.xDirection))
.clamped(min: minCropSize, max: maxCropWidth)
.clamped(min: minCropWidth, max: maxCropWidth)
let height = (lastFreeCropSize.height + (translation.height * handle.yDirection))
.clamped(min: minCropSize, max: maxCropHeight)
.clamped(min: minCropHeight, max: maxCropHeight)
freeCropSize = CGSize(width: width, height: height)
adjustTransforms(canvasSize: canvasSize, cropSize: freeCropSize)