Обрезка изображения по горизонтали с помощью UIView - PullRequest
0 голосов
/ 27 августа 2018

Я хочу обрезать изображение после захвата изображения с пользовательской камеры и для обрезки изображения, я использую этот учебник Учебник для обрезки изображения

В моем проекте я не использую scrollView, но я использую View (и я использую его как AVVideoCapturePreviewLayer)

Вот изображение раскадровки enter image description here

Предварительный просмотр для AVVideoCapturePreviewLayer

Предварительный просмотр изображения для размещения изображения после захвата изображения (ограничение аналогично предварительному просмотру)

Неподвижное изображение для обрезки изображения в предварительном изображении (соотношение сторон 16: 9), и я помещаю CropAreaView в пользовательский класс неподвижного изображения

Вот код для обрезки

var cropArea:CGRect {

    get {

        let factor = previewImage.image!.size.width/view.frame.width
        let imageFrame = previewImage.imageFrame()

        let x = (previewView.frame.origin.x + stillPicture.frame.origin.x - imageFrame.origin.x) * factor

        let y = (previewView.frame.origin.y + stillPicture.frame.origin.y - imageFrame.origin.y) * factor

        let width = stillPicture.frame.size.width  * factor
            let height = stillPicture.frame.size.height  * factor


        return CGRect(x: x, y: y, width: width, height: height)
    }
}



extension UIImageView {

        func imageFrame() -> CGRect {

            let imageViewSize = self.frame.size
            guard let imageSize = self.image?.size else {return CGRect.zero}
            let imageRatio = imageSize.width / imageSize.height
            let imageViewRatio = imageViewSize.width / imageViewSize.height



            if imageRatio < imageViewRatio {

                let scaleFactor = imageViewSize.height / imageSize.height
                let width = imageSize.width * scaleFactor
                let topleftX = (imageViewSize.width - width) * 0.5
                return CGRect (x: topleftX, y: 0, width: width, height: imageViewSize.height)

            } else {

                let scalFactor = imageViewSize.width / imageSize.width
                let height = imageSize.height * scalFactor
                let topleftY = (imageViewSize.height - height) * 0.5
                return CGRect (x: 0, y: topleftY, width: imageViewSize.width, height: height)
            }

        }
    }


    class CropAreaView: UIView {

        override func point (inside point: CGPoint, with event: UIEvent?) -> Bool {

            return false

        }
    }

А вот и для захвата изображения

        let dataSementara : UIImage = UIImage (data: dataImage)!
        previewImage.image = dataSementara


        let croppedCGImage = previewImage.image?.cgImage?.cropping(to: cropArea)
        let croppedImage = UIImage(cgImage: croppedCGImage!)
        previewImage.image = croppedImage
        takenImage = previewImage.image

Вот вид с камеры enter image description here

А вот и результат после захвата enter image description here

Я уже изменяю переменную в cropArea: CG Rect и func imageFrame () -> CGRect и все равно не повезло (все еще обрезаю горизонтально)

Вот полный код:

    class CustomCameraKTPViewController: UIViewController , AVCapturePhotoCaptureDelegate {

        @IBOutlet weak var stillPicture : CropAreaView!
        @IBOutlet weak var previewImage : UIImageView!
        @IBOutlet weak var previewView: PreviewViewKTP!


        var timer = Timer()
        var seconds = 30
        var delegate:sendDataToViewProtocol? = nil
        var takenImage : UIImage!
        var userDataPhotoCamera = userImage()
        var imageData1: NSData!
        var imageStr1: String!

        let captureSession = AVCaptureSession()
        var videoPreviewLayer: AVCaptureVideoPreviewLayer?
        let capturePhotoOutput = AVCapturePhotoOutput()
        let capturePhotoDelegate = CaptureKTPImage()


        var cropArea:CGRect {

            get {

                let factor = previewImage.image!.size.width/view.frame.width
                let imageFrame = previewImage.imageFrame()

                let x = (previewView.frame.origin.x + stillPicture.frame.origin.x - imageFrame.origin.x) * factor

                let y = (previewView.frame.origin.y + stillPicture.frame.origin.y - imageFrame.origin.y) * factor

                let width = stillPicture.frame.size.width  * factor
                    let height = stillPicture.frame.size.height  * factor


                return CGRect(x: x, y: y, width: width, height: height)
            }
        }

        override func viewDidLoad() {
            super.viewDidLoad()
            checkCameraUsagePermission()
            if takenImage != nil {

                timer.invalidate()
                dismiss (animated: true)
            }

            runTimer()
        }


        func initialiseCaptureSession() {

            let captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)

            guard let input = try? AVCaptureDeviceInput(device: captureDevice!),
                captureSession.canAddInput(input)
                else { return }

            captureSession.addInput(input)
            self.previewView.videoPreviewLayer.session = self.captureSession
            self.previewView.videoPreviewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill

            capturePhotoOutput.isHighResolutionCaptureEnabled = true
            captureSession.addOutput(capturePhotoOutput)

            captureSession.startRunning()
        }

        @IBAction func onTapTakePhoto(_ sender: UIButton) {

            timer.invalidate()

            let settings = AVCapturePhotoSettings()
            let previewPixelType = settings.availablePreviewPhotoPixelFormatTypes.first!
            let previewFormat = [kCVPixelBufferPixelFormatTypeKey as String: previewPixelType]
            settings.previewPhotoFormat = previewFormat
            capturePhotoOutput.capturePhoto(with: settings, delegate: self)


        }


        func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {

            if let error = error {

                print(error.localizedDescription)

            }

            // take the session output, get the buffer, and create an image from that buffer



            if let sampleBuffer = photoSampleBuffer, let previewBuffer = previewPhotoSampleBuffer, let dataImage = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: previewBuffer) {
                // gambar yg sudah diambil


                let dataSementara : UIImage = UIImage (data: dataImage)!
                previewImage.image = dataSementara


                let croppedCGImage = previewImage.image?.cgImage?.cropping(to: cropArea)
                let croppedImage = UIImage(cgImage: croppedCGImage!)
                previewImage.image = croppedImage
                takenImage = previewImage.image



                let expectedSizeInMb = 3
                let sizeInBytes = expectedSizeInMb * 1024 * 1024
                var needCompress:Bool = true
                var imgData:Data?
                var compressingValue:CGFloat = 1.0


                print ("\(takenImage)")

                if takenImage != nil {

                    while (needCompress && compressingValue > 0.0) {
                        if let data: Data = UIImageJPEGRepresentation(takenImage!, compressingValue) {

                            if data.count < sizeInBytes {

                                needCompress = false
                                imgData = data

                            } else {
                                compressingValue -= 0.01
                            }
                        }
                    }
                    if let data = imgData {

                        if (data.count < sizeInBytes) {

                            UIImage(data: data)
                            print ("\(data)")

                        }
                    }

                    userDataPhotoCamera.fotoID =  imgData?.base64EncodedString(options: Data.Base64EncodingOptions.lineLength64Characters)

                    if (delegate != nil) {
                        //Check textField is empty
                        if(userDataPhotoCamera.fotoID != "" || userDataPhotoCamera.fotoID != nil){
                            //set textField Data to protocol Function
                            delegate?.inputData(data: userDataPhotoCamera.fotoID!)


                            self.view.removeFromSuperview()

                        }
                    }
            } else {

                print("Error setting up photo capture")
                self.view.removeFromSuperview()
                }
            }
        }

        func checkCameraUsagePermission() {
            switch AVCaptureDevice.authorizationStatus(for: .video) {
            case .authorized:
                self.initialiseCaptureSession()

            case .notDetermined:
                AVCaptureDevice.requestAccess(for: .video) { granted in
                    if granted {
                        self.initialiseCaptureSession()
                    }
                }
            case .denied:
                return
            case .restricted:
                return
            }
        }

        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

            if (segue.identifier == "segueToPreviewKTP") {

                let destinationCamera = segue.destination as! PreviewKTPPhotoViewController
                destinationCamera.previewImage = takenImage
                destinationCamera.PreviewuserDataPhotoCamera.fotoID = userDataPhotoCamera.fotoID

                }
            }

    }


    extension CustomCameraKTPViewController {


         func runTimer() {

         timer = Timer.scheduledTimer(timeInterval: 1, target: self,   selector: (#selector(CustomCameraKTPViewController.updateTimer)), userInfo: nil, repeats: true)


         }

         @objc func updateTimer() {
         seconds -= 1     //This will decrement(count down)the seconds.
         print ("\(seconds)") //This will update the label.

         if seconds == 0 {

         //set ulang timer dan matikan
         timer.invalidate()

         let alertController = UIAlertController (title: "Error", message: "Camera otomatis mati setelah 30 detik", preferredStyle: .alert)
         let dismissAction = UIAlertAction (title: "Dismiss", style: .cancel, handler: nil)

         alertController.addAction(dismissAction)
         present (alertController, animated: true, completion: nil)
         self.view.removeFromSuperview()

         seconds = 30
         timer.invalidate()

            }
        }
    }


    extension UIImageView {

        func imageFrame() -> CGRect {

            let imageViewSize = self.frame.size
            guard let imageSize = self.image?.size else {return CGRect.zero}
            let imageRatio = imageSize.width / imageSize.height
            let imageViewRatio = imageViewSize.width / imageViewSize.height



            if imageRatio < imageViewRatio {

                let scaleFactor = imageViewSize.height / imageSize.height
                let width = imageSize.width * scaleFactor
                let topleftX = (imageViewSize.width - width) * 0.5
                return CGRect (x: topleftX, y: 0, width: width, height: imageViewSize.height)

            } else {

                let scalFactor = imageViewSize.width / imageSize.width
                let height = imageSize.height * scalFactor
                let topleftY = (imageViewSize.height - height) * 0.5
                return CGRect (x: 0, y: topleftY, width: imageViewSize.width, height: height)
                    }
        }
    }


    class CropAreaView: UIView {

        override func point (inside point: CGPoint, with event: UIEvent?) -> Bool {
        return false

        }
    }

Я очень ценю любую помощь, спасибо.

1 Ответ

0 голосов
/ 28 августа 2018

Решено изменением возврата CGRect в var cropArea: CGRect

С

    return CGRect(x: x, y: y, width: width, height: height)

К

    return CGRect(x: y, y: x, width: width, height: height)
...