[Do it!] 카메라와 포토 라이브러리 앱

CoCoral·2023년 10월 25일
1

Do it!

목록 보기
21/25
post-thumbnail

Do it! 스위프트로 아이폰 앱 만들기
15장 카메라와 포토 라이브러리에서 미디어 가져오기

📱 실행 화면 📱


💻 Step 1. 기본 환경 구성하기

  • 빈 스토리보드에 Horizontal Stack View 배치하기
    • [Add New Constraints] 에서
      위:0, 왼쪽:16, 오른쪽:16, 아래:0 으로 설정하기
  • 세로 스택 뷰 안에 Image View 배치하기
    • Content Mode: [Aspect Fit]
    • Background: [System grouped Background Color]
  • 이미지 뷰 아래에 2개의 Vertical Stack View 배치하기
  • 각 가로 스택 뷰 안에 버튼 2개씩 배치하기
  • 가로 스택 뷰 2개를 선택하고 [Attributes inspector] -> [Distribution] -> [Fill Equally] 설정하기
    • 스택 뷰 내에 있는 객체들의 크기가 모두 동일하게 맞춰진다.
  • 버튼 4개를 선택하고 [Add New Constraints] -> Height = 40 으로 설정하기
  • 버튼명 수정하기

💻 Step 2. Outlet 변수와 Action 함수 추가하기


💻 Step 3. 앱 기능 구현하기

import UIKit
import MobileCoreServices

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

    let imagePicker: UIImagePickerController! = UIImagePickerController()
    var captureImage: UIImage!
    var videoURL: URL!
    var flagImageSave = false
  • 카메라와 포토 라이브러리를 사용하기 위해 필요한 것
    • ImagePickerController
    • 위 컨트롤러를 사용하기 위한 델리게이트 프로토콜
    • 미디어 타입이 정의된 헤더 파일

func myAlert(_ title: String, message: String) {
    let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
    let action = UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil)
    alert.addAction(action)
    self.present(alert, animated: true, completion: nil)
}

경고 표시용 메소드


@IBAction func btnCaptureImageFromCamera(_ sender: UIButton) {
    if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
        flagImageSave = true
        
        imagePicker.delegate = self
        imagePicker.sourceType = .camera
        imagePicker.mediaTypes = [kUTTypeImage as String]
        imagePicker.allowsEditing = false
        
        present(imagePicker, animated: true, completion: nil)
    }
    else {
        myAlert("Camera inaccessable", message: "Application cannot access the camera.")
    }
}

사진 촬영 버튼 코드

  • 카메라 사용 가능 여부 확인
  • 이미지 저장 허용
  • 편집 불가

@IBAction func btnLoadImageFromLibrary(_ sender: UIButton) {
    if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
        flagImageSave = false
        
        imagePicker.delegate = self
        imagePicker.sourceType = .photoLibrary
        imagePicker.mediaTypes = [kUTTypeImage as String]
        imagePicker.allowsEditing = true
        
        present(imagePicker, animated: true, completion: nil)
    }
    else {
        myAlert("Photo album inaccessable", message: "Application cannot access the photo album.")
    }
}

사진 불러오기 버튼 코드

  • 포토 라이브러리 사용 가능 여부 확인
  • 이미지 저장 불가
  • 편집 허용

@IBAction func btnRecordVideoFromCamera(_ sender: UIButton) {
    if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
        flagImageSave = true
        
        imagePicker.delegate = self
        imagePicker.sourceType = .camera
        imagePicker.mediaTypes = [kUTTypeMovie as String]
        imagePicker.allowsEditing = false
        
        present(imagePicker, animated: true, completion: nil)
    }
    else {
        myAlert("Camera inaccessable", message: "Application cannot access the camera.")
    }
}

비디오 촬영 버튼 코드

  • 카메라 사용 가능 여부 확인
  • 비디오 저장 허용
  • 편집 불가

@IBAction func btnLoadVideoFromLibrary(_ sender: UIButton) {
    if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
        flagImageSave = false
        
        imagePicker.delegate = self
        imagePicker.sourceType = .photoLibrary
        imagePicker.mediaTypes = [kUTTypeMovie as String]
        imagePicker.allowsEditing = false
        
        present(imagePicker, animated: true, completion: nil)
    }
    else {
        myAlert("Photo album inaccessable", message: "Application cannot access the photo album.")
    }
}

비디오 불러오기 버튼 코드

  • 포토 라이브러리 사용 가능 여부 확인
  • 비디오 저장 불가
  • 편집 불가

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! NSString
    
    if mediaType.isEqual(to: kUTTypeImage as NSString as String) {
        captureImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
        
        if flagImageSave {
            UIImageWriteToSavedPhotosAlbum(captureImage, self, nil, nil)
        }
        
        imgView.image = captureImage
    }
    else if mediaType.isEqual(to: kUTTypeMovie as NSString as String) {
        if flagImageSave {
            videoURL = (info[UIImagePickerController.InfoKey.mediaURL] as! URL)
            
            UISaveVideoAtPathToSavedPhotosAlbum(videoURL.relativePath, self, nil, nil)
        }
    }
    
    self.dismiss(animated: true, completion: nil)
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    self.dismiss(animated: true, completion: nil)
}

델리게이트 메소드 코드

  • 카메라 촬영이 끝나거나 포토 라이브러리에서 선택이 끝났을 때 호출된다.
  • flagImageSave 값에 따라 포토 라이브러리에 미디어 저장하기
  • 마지막에 이미지 피커 컨트롤러를 제거하여 초기 뷰 보여주기
  • 촬영을 하지 않거나 포토 라이브러리에서 선택하지 않고 취소했을 경우에는 이미지 피커 컨트롤러 제거하기

💡 시뮬레이터에서는 카메라 테스트 불가


💻 Final Step. 전체 소스 코드

import UIKit
import MobileCoreServices

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

    let imagePicker: UIImagePickerController! = UIImagePickerController()
    var captureImage: UIImage!
    var videoURL: URL!
    var flagImageSave = false
    
    @IBOutlet var imgView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func btnCaptureImageFromCamera(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
            flagImageSave = true
            
            imagePicker.delegate = self
            imagePicker.sourceType = .camera
            imagePicker.mediaTypes = [kUTTypeImage as String]
            imagePicker.allowsEditing = false
            
            present(imagePicker, animated: true, completion: nil)
        }
        else {
            myAlert("Camera inaccessable", message: "Application cannot access the camera.")
        }
    }
    @IBAction func btnLoadImageFromLibrary(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
            flagImageSave = false
            
            imagePicker.delegate = self
            imagePicker.sourceType = .photoLibrary
            imagePicker.mediaTypes = [kUTTypeImage as String]
            imagePicker.allowsEditing = true
            
            present(imagePicker, animated: true, completion: nil)
        }
        else {
            myAlert("Photo album inaccessable", message: "Application cannot access the photo album.")
        }
    }
    @IBAction func btnRecordVideoFromCamera(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
            flagImageSave = true
            
            imagePicker.delegate = self
            imagePicker.sourceType = .camera
            imagePicker.mediaTypes = [kUTTypeMovie as String]
            imagePicker.allowsEditing = false
            
            present(imagePicker, animated: true, completion: nil)
        }
        else {
            myAlert("Camera inaccessable", message: "Application cannot access the camera.")
        }
    }
    @IBAction func btnLoadVideoFromLibrary(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
            flagImageSave = false
            
            imagePicker.delegate = self
            imagePicker.sourceType = .photoLibrary
            imagePicker.mediaTypes = [kUTTypeMovie as String]
            imagePicker.allowsEditing = false
            
            present(imagePicker, animated: true, completion: nil)
        }
        else {
            myAlert("Photo album inaccessable", message: "Application cannot access the photo album.")
        }
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! NSString
        
        if mediaType.isEqual(to: kUTTypeImage as NSString as String) {
            captureImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
            
            if flagImageSave {
                UIImageWriteToSavedPhotosAlbum(captureImage, self, nil, nil)
            }
            
            imgView.image = captureImage
        }
        else if mediaType.isEqual(to: kUTTypeMovie as NSString as String) {
            if flagImageSave {
                videoURL = (info[UIImagePickerController.InfoKey.mediaURL] as! URL)
                
                UISaveVideoAtPathToSavedPhotosAlbum(videoURL.relativePath, self, nil, nil)
            }
        }
        
        self.dismiss(animated: true, completion: nil)
    }
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        self.dismiss(animated: true, completion: nil)
    }
    
    func myAlert(_ title: String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
        let action = UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil)
        alert.addAction(action)
        self.present(alert, animated: true, completion: nil)
    }
}

💻 도전! Mission 콜라주 사진 만들기


import UIKit
import MobileCoreServices

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    
    let imagePicker: UIImagePickerController! = UIImagePickerController()
    var captureImage: UIImage!
    var flagImageSave = false
    var numImage = 0

    @IBOutlet var imgView1: UIImageView!
    @IBOutlet var imgView2: UIImageView!
    @IBOutlet var imgView3: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func btnCaptureImageFromCamera(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
            flagImageSave = true
            
            imagePicker.delegate = self
            imagePicker.sourceType = .camera
            imagePicker.mediaTypes = [kUTTypeImage as String]
            imagePicker.allowsEditing = false
            
            present(imagePicker, animated: true, completion: nil)
            numImage += 1
        }
        else {
            myAlert("Camera inaccessable", message: "Application cannot access the camera.")
        }
    }
    @IBAction func btnLoadImageFromLibrary(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
            flagImageSave = false
            
            imagePicker.delegate = self
            imagePicker.sourceType = .photoLibrary
            imagePicker.mediaTypes = [kUTTypeImage as String]
            imagePicker.allowsEditing = true
            
            present(imagePicker, animated: true, completion: nil)
            numImage += 1
        }
        else {
            myAlert("Photo album inaccessible", message: "Application cannot access the photo album.")
        }
    }
    @IBAction func initImageView(_ sender: UIButton) {
        imgView1.image = nil
        imgView2.image = nil
        imgView3.image = nil
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! NSString
        
        if mediaType.isEqual(to: kUTTypeImage as NSString as String) {
            captureImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
            
            if flagImageSave {
                UIImageWriteToSavedPhotosAlbum(captureImage, self, nil, nil)
            }
            
            switch numImage {
            case 1:
                imgView1.image = captureImage
                break
            case 2:
                imgView2.image = captureImage
                break
            case 3:
                imgView3.image = captureImage
                break
            default:
                break
            }
        }
        
        self.dismiss(animated: true, completion: nil)
    }
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        numImage -= 1
        self.dismiss(animated: true, completion: nil)
    }
    
    func myAlert(_ title:String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
        let action = UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil)
        alert.addAction(action)
        self.present(alert, animated: true, completion: nil)
    }
}
profile
언젠간 iOS 개발자가 되겠지

0개의 댓글