気がついたら dngPhotoDataRepresentation() API が deprecated扱いになっておりました💦 さしあたって昔の APIのままでも良いわけですが、尻カッチンになってからの修正はつらいので少し調査。ほとんど資料がないのですがとりあえずこのコードで動作しているようです。
コードの流れは以前のものと殆ど同じです。
初期化:
override func viewDidLoad() { super.viewDidLoad() self.captureSession = AVCaptureSession() self.captureSession?.sessionPreset = .photo self.capturePhotoOutput = AVCapturePhotoOutput() self.captureDevice = AVCaptureDevice.default(for: .video) let input = try! AVCaptureDeviceInput(device: self.captureDevice!) self.captureSession?.addInput(input) self.captureSession?.addOutput(self.capturePhotoOutput!) self.previewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession!) self.previewLayer?.frame = self.preView.bounds self.previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill self.previewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait self.preView.layer.addSublayer(self.previewLayer!) self.captureSession?.startRunning() }
キャプチャ:
@IBAction func capture(_ sender: Any) { let photoSettings : AVCapturePhotoSettings! guard let availableRawFormat = capturePhotoOutput?.__availableRawPhotoPixelFormatTypes.first else { return } photoSettings = AVCapturePhotoSettings(rawPixelFormatType: availableRawFormat.uint32Value) photoSettings.isAutoStillImageStabilizationEnabled = false photoSettings.flashMode = .off photoSettings.isHighResolutionPhotoEnabled = false let desiredPreviewPixelFormat = NSNumber(value: kCVPixelFormatType_32BGRA) if photoSettings.__availablePreviewPhotoPixelFormatTypes.contains(desiredPreviewPixelFormat) { photoSettings.previewPhotoFormat = [ kCVPixelBufferPixelFormatTypeKey as String : desiredPreviewPixelFormat, kCVPixelBufferWidthKey as String : NSNumber(value: 512), kCVPixelBufferHeightKey as String : NSNumber(value: 512) ] } self.capturePhotoOutput?.capturePhoto(with: photoSettings, delegate: self) }
保存:
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { let dir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! as String let formatter = DateFormatter() formatter.dateFormat = "yyyyMMddHHmmss" formatter.locale = Locale.init(identifier: "en_US_POSIX") let filePath = dir.appending(String(format: "/%@.dng", formatter.string(from: Date()))) let dngFileURL = URL(fileURLWithPath: filePath) let dngData = photo.fileDataRepresentation()! do { try dngData.write(to: dngFileURL, options: []) } catch { print("Unable to write DNG file.") return } let items = [dngFileURL] let activityView = UIActivityViewController.init(activityItems: items, applicationActivities: nil) activityView.popoverPresentationController?.sourceView = self.view activityView.excludedActivityTypes = [ UIActivityType.copyToPasteboard, UIActivityType.assignToContact, UIActivityType.openInIBooks, ] self.present(activityView, animated: true, completion: nil) }
* Photo Libraryには保存できないようで(白い画像らしきものは保存されましたが)、ローカルに保存して共有する方法がよいのではないでしょうか。
使い方: “Capture”ボタンで撮影、直後にアクティビティが立ち上がるので好きなアプリで共有してください。
ご参考までに😗 プロジェクト一式は → GitHub.
- Tags
- iOS 11, Photo Capture, Sample Code, Swift 4, Xcode9