// // CustomCameraViewController.swift // MCPlus // // Created by seo ha on 31/01/2019. // Copyright © 2019 KangSH. All rights reserved. // import UIKit import AVFoundation import ReactiveCocoa import ReactiveSwift class CustomCameraViewController: UIViewController { @IBOutlet weak var patientIdLabel :UILabel!{ didSet{ patientIdLabel.reactive.text <~ PictureViewController.patientId } } @IBOutlet weak var patientNmLabel :UILabel!{ didSet{ patientNmLabel.reactive.text <~ PictureViewController.patientNm } } @IBOutlet weak var ageGenderLabel :UILabel!{ didSet{ ageGenderLabel.reactive.text <~ PictureViewController.ageGender } } @IBOutlet weak var previewView: UIView! //사진 촬영 버튼 @IBOutlet weak var takePhoto: UIButton!{ didSet{ takePhoto.addTapGestureRecognizer(action: self.takeAction) } } @IBOutlet weak var finishButton: UIButton!{ didSet{ finishButton.addTapGestureRecognizer(action: self.finish) } } @IBOutlet weak var albumButton: UIButton!{ didSet{ albumButton.addTapGestureRecognizer(action: self.albumAction) } } @IBOutlet weak var closeButton: UIImageView!{ didSet{ closeButton.addTapGestureRecognizer(action: self.finish) } } @IBOutlet weak var deptNmLabel: UILabel!{ didSet{ PictureViewController.deptNm.signal.observe { [weak deptNmLabel](item) in guard let value = item.value as? String else{ return } let attr = deptNmLabel?.attributedText?.attributes(at: 0, effectiveRange: nil) let attrString = NSMutableAttributedString(string: value, attributes: attr) deptNmLabel?.attributedText = attrString } } } @IBOutlet weak var treatClsKrLabel: UILabel!{ didSet{ PictureViewController.treatClsKr.signal.observe { [weak treatClsKrLabel](item) in guard let value = item.value as? String else{ return } let attr = treatClsKrLabel?.attributedText?.attributes(at: 0, effectiveRange: nil) let attrString = NSMutableAttributedString(string: value, attributes: attr) treatClsKrLabel?.attributedText = attrString } } } @IBOutlet weak var doctorNmLabel: UILabel!{ didSet{ PictureViewController.doctorNm.signal.observe { [weak doctorNmLabel](item) in guard let value = item.value as? String else{ return } let attr = doctorNmLabel?.attributedText?.attributes(at: 0, effectiveRange: nil) let attrString = NSMutableAttributedString(string: value, attributes: attr) doctorNmLabel?.attributedText = attrString } } } @IBOutlet weak var titleLabel: UILabel!{ didSet{ titleLabel.reactive.text <~ PictureViewController.titles } } var session: AVCaptureSession? var stillImageOutput:AVCaptureStillImageOutput{ let stillImageOutput = AVCaptureStillImageOutput() stillImageOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG] return stillImageOutput } @available(iOS 11.0, *) lazy var newStillImageOutput: AVCapturePhotoOutput = AVCapturePhotoOutput() var videoPreviewLayer: AVCaptureVideoPreviewLayer? static var photoProcessCommit = MutableProperty(nil) } extension CustomCameraViewController{ override func viewDidLoad() { super.viewDidLoad() session = AVCaptureSession() session!.sessionPreset = AVCaptureSession.Preset.photo let backCamera = AVCaptureDevice.default(for: AVMediaType.video) var error: NSError? var input: AVCaptureDeviceInput! do { if let camera = backCamera{ input = try AVCaptureDeviceInput(device: camera) } } catch let error1 as NSError { error = error1 input = nil print(error!.localizedDescription) } if error == nil && session!.canAddInput(input) { session!.addInput(input) if session!.canAddOutput(stillImageOutput) { if #available(iOS 11.0, *) { session!.addOutput(newStillImageOutput) }else{ session!.addOutput(stillImageOutput) } videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session!) videoPreviewLayer!.videoGravity = AVLayerVideoGravity.resizeAspect videoPreviewLayer!.connection?.videoOrientation = AVCaptureVideoOrientation.portrait previewView.layer.addSublayer(videoPreviewLayer!) videoPreviewLayer?.videoGravity = .resizeAspectFill session!.startRunning() } } } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: { (granted: Bool) -> Void in if granted == true { // User granted } else { // User rejected self.showAlert("카메라 권한이 없습니다. 권한에 동의해 주세요.", "", "확인", nil, { [weak self](action) in self?.finish() }) } }) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() videoPreviewLayer?.frame = previewView.bounds } func finish(){ self.navigationController?.popViewController(animated: true) } func albumAction(){ if let parent = self.parent as? PictureViewController{ parent.gallaryAction(action: nil) } } func takeAction(){ if #available(iOS 11.0, *) { let settings = AVCapturePhotoSettings() settings.livePhotoVideoCodecType = .jpeg newStillImageOutput.capturePhoto(with: settings, delegate: self) }else{ guard let connection = stillImageOutput.connection(with: AVMediaType.video) else { return } stillImageOutput.captureStillImageAsynchronously(from: connection, completionHandler: { [weak self](buffer, error) in if let _ = error{ return } guard let buffer = buffer else{ return } if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer){ let image = UIImage(data: imageData) self?.processingImage(image: image) } }) } } func processingImage(image:UIImage?){ if let image = image{ if let data: Data = image.pngData(){ if data.format == "unknown"{ self.showAlert("환부이미지 촬영을 이용하시려면 라이브포토 기능을 off해주세요.", "", "확인") return } } DispatchQueue(label: "background").async{ [weak self] in guard let `self` = self else{ return } let datas = [image] .map(self.resizableTaransform) .map(self.optimisingTransform) //도큐먼트의 유저 디렉토리를 찾는다 if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { let path = dir.appendingPathComponent("kunkuk") //해당 폴더가 없으면 생성 if !FileManager.default.fileExists(atPath: path.path){ try? FileManager.default.createDirectory(at: path, withIntermediateDirectories: true, attributes: nil) } let thumb = dir.appendingPathComponent("thumb") //해당 폴더가 없으면 생성 if !FileManager.default.fileExists(atPath: thumb.path){ try? FileManager.default.createDirectory(at: thumb, withIntermediateDirectories: true, attributes: nil) } //각 데이터 저장 for data in datas{ let date = Date() let file = "kunkuk_\(date.fromString(format: "yyyyMMddhhmmss")).jpg" let fileURL = path.appendingPathComponent(String(file)) let thumbURL = thumb.appendingPathComponent(String(file)) try? data?.write(to: fileURL) let origin = UIImage(data: data!) try? self.getThumbnailData(image: origin!)?.write(to: thumbURL) do { guard let parent = self.parent as? PictureViewController else{ return } let date = Date().fromString(format: "yyyy-MM-dd") let name = parent.user?.patientNm ?? "" var treatCls = "" let deptNm = parent.user?.deptNm ?? "" switch parent.user?.treatCls{ //외래 case "O"?: treatCls = "외래" //입원 case "I"?: treatCls = "입원" //응급 case "E"?: treatCls = "응급" default: break } let photo = Photo() photo.user = parent.user photo.file = file photo.date = date photo.key = "\(date) \(name) \(treatCls), \(deptNm)" photo.isSended = false photo.save() //노티피케이션 알림 CustomCameraViewController.photoProcessCommit.value = photo } } } } } } func resizableTaransform(image:UIImage) -> UIImage { let width = image.size.width let height = image.size.height var ratio:CGFloat = 1.0 if width > 1280{ ratio = width / 1280 } return image.scaleToSize(newSize: CGSize(width: width / ratio, height: height / ratio)) } func optimisingTransform(image:UIImage) -> Data? { return image.jpegData(compressionQuality: 0.7) } func getThumbnailData(image:UIImage) -> Data? { let datas = [image] .map(resizableTaransform) .map(optimisingTransform) return datas.first! } } extension CustomCameraViewController: AVCapturePhotoCaptureDelegate{ @available(iOS 11.0, *) func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { guard error == nil else{ return } guard let imageData = photo.fileDataRepresentation() else{ return } let image = UIImage(data: imageData) self.processingImage(image: image) } }