UIImagePickerController

이하연·2021년 9월 16일
1

[Swift] 스위프트

목록 보기
25/27

UIImagePickerController 객체 생성

private let imagePickerController = UIImagePickerController()

앨범 접근

@IBAction private func pickImage(_ sender: Any){
		present(imagePickerController, animated: true, completion: nil)
		
		public enum UIImagePickerControllerSourceType: Int{
				case photoLibrary
				case camera
				case savedPhotoAlbum

		let type = UIImagePickerControllerSourceType.photoLibrary
		guard UIImagePickerController.isSourceType
}

카메라 접근

  • plist에서 Privacy - Camera Usage Description 넣어 주기
  • allowsEditing이란 촬영후 편집 화면
@IBAction private func takePicture(_ sender: Any){

		// 카메라 사용가능한지 체크
		guard UIImagePickerController.isSourceTypeAvailable(.camera) else { return }
		imagePickerController.sourceType = .camera

		// 촬영후 편집할 수 있는 부분이 나온다.
		imagePickerController.allowsEditing = true

		present(imagePickerController, animated: true, completion: nil)
}

동영상 촬영

  • cameraCaptureMode 2가지 종류 - .video 와 .photo(default)

  • 사용가능한 imagePickerController의 mediaTypes
    → [“public.image”, “public.movie”]

  • 에러

    • video는 public.movie가 포함되있어야되는데 포함해주지 않아서

    • 동영상 촬영시 소리도 같이 들어가야하므로 마이크 접근 허용 필요

      • plist에 Privacy - Microphone Usage Description 추가
@IBAction private func recordingVideo(_ sender: Any) {
    guard UIImagePickerController.isSourceTypeAvailable(.camera) else { return }
    imagePickerController.sourceType = .camera

    // 이 부분이 추가되었습니다.
		imagePickerController.mediaTypes = ["pulic.movie"]
    imagePickerController.cameraCaptureMode = .video

		// 카메라 정면, 후면 설정 .rear .front
		imagePickerController.cameraDevice = .rear
		// 플래쉬 작동 모드 .on .off .auto
		imagePickerController.cameraFlashMode = .on

    present(imagePickerController, animated: true, completion: nil)

		//현재 imagePickerController의 mediaTypes
		print(imagePickerController.mediaTypes) // public.image
		//사용가능한 imagePickerController의 mediaTypes
		print(UIImagePickerController.availableMediaTypes(for: .camera) ?? []) // ["public.image", "public.movie"]
}

편집하기 (변경)

@IBAction private func toggleAllowsEditing(_ sender: Any) {
    // 누를때 마다 반대가 되게
    imagePickerController.allowsEditing = !imagePickerController.allowsEditing
}

그 이후 해야할 것들

UIImagePickerControllerDelegate = 이미지를 선택하고 카메라를 찍었을 때 다양한 동작을 도와줍니다.

UINavigationControllerDelegate = 앨범 사진을 선택했을 때, 화면 전환을 네비게이션으로 이동합니다.

Q : UIImagePickerControllerDelegate를 선언 할 때 UINavigationControllerDelegate를 선언해야하는 이유를 분명히 알 수 있을까?

  • A
    UIImagePickerControllerDelegate의 delegate 속성은 UIImagePickerControllerDelegate와 UINavigationControllerDelegate 프로토콜을 모두 구현하는 객체로 정의되어있다.
    picker.delegate =  self에서의 self를  picker.delegate에 할당하려면 self는 UINavigationControllerDelegate 타입이어야 한다.
    지금, picker의 델리게이트를 UINavigationControllerDelegate에 위임해준 것인데, 대리자는 사용자가 이미 지나 동영상을 선택하거나 picker화면을 종료할 때, 알림을 받는다.

Delegate 구성

  • 앨범에서 사진들의 정보를 가져오거나 촬영 후 저장하기 위해서는 Delegate를 구성해야합니다. 하지만 UIImagePickerControllerDelegate만 구성할 수는 없습니다. 같이 연결되어 있기 때문에 UINavigationControllerDelegate도 같이 채택해야됩니다.
// 같이 연결 되어있기 때문에 UIImagePickerControllerDelegate, UINavigationControllerDelegate같이 채택해야된다.
 weak open var delegate: (UIImagePickerControllerDelegate & UINavigationControllerDelegate)?

Delegate 구현

  • UIImagePickerControllerDelegate는 2가지가 있습니다.
//picking을 했을때
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { }

//취소 했을때
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { }
  • Dictionary 타입은 info에 정보들이 들어옵니다.
  • UTTypeEqual 메서드를 사용 → import MobileCoreServices 해주기
  • info[UIImagePickerControllerOriginalImage]에서 pathExtension(확장자)를 가지고 동영상 부분과 사진 촬영부분을 분기할 수 있습니다.
  • plist에서 Privacy - Photo Library Additions Usage Description
import MobileCoreServices

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]
{
    //info에 정보들이 들어있다! Dictionary타입
    print("didFinishPickingMediaWithInfo,", info)

    let mediaType = info[UIImagePickerControllerMediaType] as! NSString

    // 1번!
    if UTTypeEqual(mediaType, kUTTypeMovie) {
        // 동영상 촬영 정보가 넘어 옴

        let urlPath = info[UIImagePickerControllerMediaURL] as! NSURL
        if let path = urlPath.path {
            // video를 저장하는 메서드
            UISaveVideoAtPathToSavedPhotosAlbum(path, nil, nil, nil)
        }
    } else {
        // 사진 촬영, 이미지 정보가 넘어옴
        let originalImage = info[UIImagePickerControllerOriginalImage] as! UIImage // as? UIImage를 해도된다.
            let editedImage = info[UIImagePickerControllerEditedImage] as? UIImage
            let selectedImage = editedImage ?? originalImage // editedImage가 nil이면 originalImage를 넣으라는 뜻
            imageView.image = selectedImage

            //2번!
            UIImageWriteToSavedPhotosAlbum(selectedImage, nil, nil, nil) // 이미지를 저장하는 메서드

            // Delegate 메서드가 구현되어 있지 않을 때는 기본적으로 선택시 종료되도록 기본 구현이 되어있음. ( 그래서 dismiss를 해주어야된다. )
        picker.dismiss(animated: true, completion: nil)
    }
}
//이미지 앨범에 저장 하는 메서드
public func UIImageWriteToSavedPhotosAlbum(_ image: UIImage, _ completionTarget: Any?, _ completionSelector: Selector?, _ contextInfo: UnsafeMutableRawPointer?) 

//동영상 앨범에 저장하는 메서드
public func UISaveVideoAtPathToSavedPhotosAlbum(_ videoPath: String, _ completionTarget: Any?, _ completionSelector: Selector?, _ contextInfo: UnsafeMutableRawPointer?)
이제 사진 및 동영상 저장이 정상적으로 저장이 될겁니다.

딜레이 촬영

참고자료

iOS ) 내 사진앨범/카메라에서 이미지 가져오기

0개의 댓글