SwiftUI-缩放,缩放和裁剪图像

时间:2020-01-23 17:37:25

标签: swift swiftui

link to repository编辑。

我正在使用SwiftUI,因此无法访问“裁剪视图”。我使用手势而不是ScrollView来捕获图像的缩放级别和偏移(x和y)。我无法返回基于这些因素正确裁剪的图像。

似乎SwiftUI本身可能是一个因素。也许在确定偏移量和缩放级别时需要考虑视图中图像的偏移量?

我有图像,并且从视图中的手势中获得了以下值,以表示比例和x / y位置:

string body = (String)GetLocalResourceObject("EmailTemplate");
body.Replace("[PLACEHOLDER_TITLE]", title);
body.Replace("[PLACEHOLDER_CONTENT]", content);
...

当前尝试,它最接近于名为:

的函数
 @State var scale: CGFloat = 1.0
 @State var currentPosition: CGSize = CGSize.zero

但是,正如您将在存储库中看到的那样,将缩放/缩放和x / y偏移量组合在一起时,总是有点“偏离”。

同样,当您尝试裁剪为正方形图像时,“关闭”的数量可能非常重要。

2 个答案:

答案 0 :(得分:0)

感谢Asperi's answer,我实现了一个轻量级的swiftUI库来裁剪图像。这里是库和演示。Here

魔术在下面:

    public var body: some View {
        GeometryReader { proxy  in
           // ...
                        
                        Button(action: {
  // how to crop the image according to rectangle area
                            if self.tempResult == nil {
                                self.cropTheImageWithImageViewSize(proxy.size)
                            }
                            self.resultImage = self.tempResult
                        })  {
            Text("Crop Image")
                .padding(.all, 10)
                .background(Color.blue)
                .foregroundColor(.white)
                .shadow(color: .gray, radius: 1)
                .padding(.top, 50)
        }
                    }
  }

func cropTheImageWithImageViewSize(_ size: CGSize) {

    let imsize =  inputImage.size
    let scale = max(inputImage.size.width / size.width,
                    inputImage.size.height / size.height)

    
    let zoomScale = self.scale

    let currentPositionWidth = self.dragAmount.width * scale
        let currentPositionHeight = self.dragAmount.height * scale
    
    let croppedImsize = CGSize(width: (self.cropSize.width * scale) / zoomScale, height: (self.cropSize.height * scale) / zoomScale)
     
    let xOffset = (( imsize.width - croppedImsize.width) / 2.0) - (currentPositionWidth  / zoomScale)
    let yOffset = (( imsize.height - croppedImsize.height) / 2.0) - (currentPositionHeight  / zoomScale)
    let croppedImrect: CGRect = CGRect(x: xOffset, y: yOffset, width: croppedImsize.width, height: croppedImsize.height)
          
    if let cropped = inputImage.cgImage?.cropping(to: croppedImrect) {
       //uiimage here can write to data in png or jpeg
        let croppedIm = UIImage(cgImage: cropped)
        tempResult = croppedIm
        result = Image(uiImage: croppedIm)
    }
}

答案 1 :(得分:-2)

答案由juanj通过GitHub存储库提供

let imageToManipulate =  UIImage(named: "landscape")
let zoomScale = self.scale
let imsize = imageToManipulate!.size

var scale : CGFloat = self.frameSize.width / imsize.width
if imsize.height * scale < self.frameSize.height {
 scale = self.frameSize.height / imsize.height
}
let currentPositionWidth = self.currentPosition.width / scale
let currentPositionHeight = self.currentPosition.height / scale
let croppedImsize = CGSize(width: (self.frameSize.width/scale) / zoomScale, height: (self.frameSize.height/scale) / zoomScale)
let xOffset = (( imsize.width - croppedImsize.width ) / 2.0) - (currentPositionWidth / zoomScale)
let yOffset = (( imsize.height - croppedImsize.height) / 2.0) - (currentPositionHeight / zoomScale)
let croppedImrect: CGRect = CGRect(x: xOffset, y: yOffset, width: croppedImsize.width, height: croppedImsize.height)

let r = UIGraphicsImageRenderer(size:croppedImsize)
let croppedIm = r.image { _ in
            imageToManipulate!.draw(at: CGPoint(x:-croppedImrect.origin.x, y:-croppedImrect.origin.y))
        }
self.croppedImage = croppedIm
self.photoIsFinished = true

完整的代码可以证明viewed in the repository,以演示如何允许用户缩放和平移SwiftUI视图中的框架内的图像,然后将结果裁剪为新图像。