gpt4 book ai didi

ios - 使用 UIView 水平裁剪图像

转载 作者:行者123 更新时间:2023-11-30 11:12:31 25 4
gpt4 key购买 nike

我想在从自定义相机捕获图像后裁剪图像,对于裁剪图像,我正在使用本教程 Tutorial for crop image

在我的项目中,我没有使用scrollView,但我正在使用View(并且我将它用作AVVideoCapturePreviewLayer)

这是 Storyboard的图像 enter image description here

AVVideoCapturePreviewLayer 的预览 View

预览图像,用于在捕获图像后放置图像(约束与预览 View 相同)

用于在预览图像中裁剪图像的静态图片(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

这是相机 View 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

}
}

非常感谢您的帮助,谢谢。

最佳答案

通过更改 var CropArea:CGRect 中的返回 CGRect 来解决

来自

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

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

关于ios - 使用 UIView 水平裁剪图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52037861/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com