CustomCameraViewController.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. //
  2. // CustomCameraViewController.swift
  3. // MCPlus
  4. //
  5. // Created by seo ha on 31/01/2019.
  6. // Copyright © 2019 KangSH. All rights reserved.
  7. //
  8. import UIKit
  9. import AVFoundation
  10. import ReactiveCocoa
  11. import ReactiveSwift
  12. class CustomCameraViewController: UIViewController {
  13. @IBOutlet weak var patientIdLabel :UILabel!{
  14. didSet{
  15. patientIdLabel.reactive.text <~ PictureViewController.patientId
  16. }
  17. }
  18. @IBOutlet weak var patientNmLabel :UILabel!{
  19. didSet{
  20. patientNmLabel.reactive.text <~ PictureViewController.patientNm
  21. }
  22. }
  23. @IBOutlet weak var ageGenderLabel :UILabel!{
  24. didSet{
  25. ageGenderLabel.reactive.text <~ PictureViewController.ageGender
  26. }
  27. }
  28. @IBOutlet weak var previewView: UIView!
  29. //사진 촬영 버튼
  30. @IBOutlet weak var takePhoto: UIButton!{
  31. didSet{
  32. takePhoto.addTapGestureRecognizer(action: self.takeAction)
  33. }
  34. }
  35. @IBOutlet weak var finishButton: UIButton!{
  36. didSet{
  37. finishButton.addTapGestureRecognizer(action: self.finish)
  38. }
  39. }
  40. @IBOutlet weak var albumButton: UIButton!{
  41. didSet{
  42. albumButton.addTapGestureRecognizer(action: self.albumAction)
  43. }
  44. }
  45. @IBOutlet weak var closeButton: UIImageView!{
  46. didSet{
  47. closeButton.addTapGestureRecognizer(action: self.finish)
  48. }
  49. }
  50. @IBOutlet weak var deptNmLabel: UILabel!{
  51. didSet{
  52. PictureViewController.deptNm.signal.observe { [weak deptNmLabel](item) in
  53. guard let value = item.value as? String else{ return }
  54. let attr = deptNmLabel?.attributedText?.attributes(at: 0, effectiveRange: nil)
  55. let attrString = NSMutableAttributedString(string: value, attributes: attr)
  56. deptNmLabel?.attributedText = attrString
  57. }
  58. }
  59. }
  60. @IBOutlet weak var treatClsKrLabel: UILabel!{
  61. didSet{
  62. PictureViewController.treatClsKr.signal.observe { [weak treatClsKrLabel](item) in
  63. guard let value = item.value as? String else{ return }
  64. let attr = treatClsKrLabel?.attributedText?.attributes(at: 0, effectiveRange: nil)
  65. let attrString = NSMutableAttributedString(string: value, attributes: attr)
  66. treatClsKrLabel?.attributedText = attrString
  67. }
  68. }
  69. }
  70. @IBOutlet weak var doctorNmLabel: UILabel!{
  71. didSet{
  72. PictureViewController.doctorNm.signal.observe { [weak doctorNmLabel](item) in
  73. guard let value = item.value as? String else{ return }
  74. let attr = doctorNmLabel?.attributedText?.attributes(at: 0, effectiveRange: nil)
  75. let attrString = NSMutableAttributedString(string: value, attributes: attr)
  76. doctorNmLabel?.attributedText = attrString
  77. }
  78. }
  79. }
  80. @IBOutlet weak var titleLabel: UILabel!{
  81. didSet{
  82. titleLabel.reactive.text <~ PictureViewController.titles
  83. }
  84. }
  85. var session: AVCaptureSession?
  86. var stillImageOutput:AVCaptureStillImageOutput{
  87. let stillImageOutput = AVCaptureStillImageOutput()
  88. stillImageOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
  89. return stillImageOutput
  90. }
  91. @available(iOS 11.0, *)
  92. lazy var newStillImageOutput: AVCapturePhotoOutput = AVCapturePhotoOutput()
  93. var videoPreviewLayer: AVCaptureVideoPreviewLayer?
  94. static var photoProcessCommit = MutableProperty<Photo?>(nil)
  95. }
  96. extension CustomCameraViewController{
  97. override func viewDidLoad() {
  98. super.viewDidLoad()
  99. session = AVCaptureSession()
  100. session!.sessionPreset = AVCaptureSession.Preset.photo
  101. let backCamera = AVCaptureDevice.default(for: AVMediaType.video)
  102. var error: NSError?
  103. var input: AVCaptureDeviceInput!
  104. do {
  105. if let camera = backCamera{
  106. input = try AVCaptureDeviceInput(device: camera)
  107. }
  108. } catch let error1 as NSError {
  109. error = error1
  110. input = nil
  111. print(error!.localizedDescription)
  112. }
  113. if error == nil && session!.canAddInput(input) {
  114. session!.addInput(input)
  115. if session!.canAddOutput(stillImageOutput) {
  116. if #available(iOS 11.0, *) {
  117. session!.addOutput(newStillImageOutput)
  118. }else{
  119. session!.addOutput(stillImageOutput)
  120. }
  121. videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session!)
  122. videoPreviewLayer!.videoGravity = AVLayerVideoGravity.resizeAspect
  123. videoPreviewLayer!.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
  124. previewView.layer.addSublayer(videoPreviewLayer!)
  125. videoPreviewLayer?.videoGravity = .resizeAspectFill
  126. session!.startRunning()
  127. }
  128. }
  129. }
  130. override func viewDidAppear(_ animated: Bool) {
  131. super.viewDidAppear(animated)
  132. AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: { (granted: Bool) -> Void in
  133. if granted == true {
  134. // User granted
  135. } else {
  136. // User rejected
  137. self.showAlert("카메라 권한이 없습니다. 권한에 동의해 주세요.", "", "확인", nil, { [weak self](action) in
  138. self?.finish()
  139. })
  140. }
  141. })
  142. }
  143. override func viewDidLayoutSubviews() {
  144. super.viewDidLayoutSubviews()
  145. videoPreviewLayer?.frame = previewView.bounds
  146. }
  147. func finish(){
  148. self.navigationController?.popViewController(animated: true)
  149. }
  150. func albumAction(){
  151. if let parent = self.parent as? PictureViewController{
  152. parent.gallaryAction(action: nil)
  153. }
  154. }
  155. func takeAction(){
  156. if #available(iOS 11.0, *) {
  157. let settings = AVCapturePhotoSettings()
  158. settings.livePhotoVideoCodecType = .jpeg
  159. newStillImageOutput.capturePhoto(with: settings, delegate: self)
  160. }else{
  161. guard let connection = stillImageOutput.connection(with: AVMediaType.video) else {
  162. return
  163. }
  164. stillImageOutput.captureStillImageAsynchronously(from: connection, completionHandler: { [weak self](buffer, error) in
  165. if let _ = error{
  166. return
  167. }
  168. guard let buffer = buffer else{
  169. return
  170. }
  171. if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer){
  172. let image = UIImage(data: imageData)
  173. self?.processingImage(image: image)
  174. }
  175. })
  176. }
  177. }
  178. func processingImage(image:UIImage?){
  179. if let image = image{
  180. if let data: Data = image.pngData(){
  181. if data.format == "unknown"{
  182. self.showAlert("환부이미지 촬영을 이용하시려면 라이브포토 기능을 off해주세요.", "", "확인")
  183. return
  184. }
  185. }
  186. DispatchQueue(label: "background").async{ [weak self] in
  187. guard let `self` = self else{ return }
  188. let datas = [image]
  189. .map(self.resizableTaransform)
  190. .map(self.optimisingTransform)
  191. //도큐먼트의 유저 디렉토리를 찾는다
  192. if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
  193. let path = dir.appendingPathComponent("kunkuk")
  194. //해당 폴더가 없으면 생성
  195. if !FileManager.default.fileExists(atPath: path.path){
  196. try? FileManager.default.createDirectory(at: path, withIntermediateDirectories: true, attributes: nil)
  197. }
  198. let thumb = dir.appendingPathComponent("thumb")
  199. //해당 폴더가 없으면 생성
  200. if !FileManager.default.fileExists(atPath: thumb.path){
  201. try? FileManager.default.createDirectory(at: thumb, withIntermediateDirectories: true, attributes: nil)
  202. }
  203. //각 데이터 저장
  204. for data in datas{
  205. let date = Date()
  206. let file = "kunkuk_\(date.fromString(format: "yyyyMMddhhmmss")).jpg"
  207. let fileURL = path.appendingPathComponent(String(file))
  208. let thumbURL = thumb.appendingPathComponent(String(file))
  209. try? data?.write(to: fileURL)
  210. let origin = UIImage(data: data!)
  211. try? self.getThumbnailData(image: origin!)?.write(to: thumbURL)
  212. do {
  213. guard let parent = self.parent as? PictureViewController else{ return }
  214. let date = Date().fromString(format: "yyyy-MM-dd")
  215. let name = parent.user?.patientNm ?? ""
  216. var treatCls = ""
  217. let deptNm = parent.user?.deptNm ?? ""
  218. switch parent.user?.treatCls{
  219. //외래
  220. case "O"?:
  221. treatCls = "외래"
  222. //입원
  223. case "I"?:
  224. treatCls = "입원"
  225. //응급
  226. case "E"?:
  227. treatCls = "응급"
  228. default:
  229. break
  230. }
  231. let photo = Photo()
  232. photo.user = parent.user
  233. photo.file = file
  234. photo.date = date
  235. photo.key = "\(date) \(name) \(treatCls), \(deptNm)"
  236. photo.isSended = false
  237. photo.save()
  238. //노티피케이션 알림
  239. CustomCameraViewController.photoProcessCommit.value = photo
  240. }
  241. }
  242. }
  243. }
  244. }
  245. }
  246. func resizableTaransform(image:UIImage) -> UIImage {
  247. let width = image.size.width
  248. let height = image.size.height
  249. var ratio:CGFloat = 1.0
  250. if width > 1280{
  251. ratio = width / 1280
  252. }
  253. return image.scaleToSize(newSize: CGSize(width: width / ratio, height: height / ratio))
  254. }
  255. func optimisingTransform(image:UIImage) -> Data? {
  256. return image.jpegData(compressionQuality: 0.7)
  257. }
  258. func getThumbnailData(image:UIImage) -> Data? {
  259. let datas = [image]
  260. .map(resizableTaransform)
  261. .map(optimisingTransform)
  262. return datas.first!
  263. }
  264. }
  265. extension CustomCameraViewController: AVCapturePhotoCaptureDelegate{
  266. @available(iOS 11.0, *)
  267. func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
  268. guard error == nil else{ return }
  269. guard let imageData = photo.fileDataRepresentation() else{ return }
  270. let image = UIImage(data: imageData)
  271. self.processingImage(image: image)
  272. }
  273. }