我想在自定义相机中捕获图像后裁剪图像,对于裁剪图像,我正在使用本教程Tutorial for crop image
在我的项目中,我没有使用scrollView,而是使用View(并且将其用作AVVideoCapturePreviewLayer)
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
我已经更改了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
}
}
非常感谢您的帮助。
答案 0 :(得分:0)
通过更改var cropArea:CGRect中的返回CGRect来解决
来自
return CGRect(x: x, y: y, width: width, height: height)
收件人
return CGRect(x: y, y: x, width: width, height: height)