UIImage를 카메라롤에 저장하기

UIImage를 아이폰의 카메라롤에 저장하는 과정은 사실 간단하다. 카메라롤은 내부에 사진을 정리/저장할 수 있는 체계를 가지고 있는 시스템이고, 여기에 특정 이미지를 저장하겠다는 함수를 호출하는 것으로 해당 동작을 처리할 수 있다. UIImageWriteToSavedPhotosAlbum()이라는 이름을 잘못쓰기 쉽게끔 지어놓은 UIKit 자유 함수가 여기에 사용된다. 이 함수의 원형은 다음과 같다.

void UIImageWriteToSavedPhotosAlbum(
    UIImage*  image, 
    id        completeionTarget, 
    SEL       completionselector, 
    void*     contextInfo
);

이 함수는 넘겨 받은 이미지를 카메라롤에 저장하고, 저장 작업이 완료되면 지정된 타깃에 지정된 메시지를 보낸다. 각 파라미터들은 원형에서도 짐작할 수 있겠지만, 다음과 같다.

  • image : UIImage 객체
  • completionTarget : 저장이 완료된 후 콜백을 받을 객체.  콜백처리가 귀찮으면 그냥 nil을 넘긴다.
  • completionSelector: target이 받게될 완료 콜백 메소드
  • contextInfo : 특정한 컨텍스트 정보를 넘겨서 이 정보를 다시 콜백 메소드가 받아 처리한다. 보통의 경우에는 그냥 nil을 넘긴다.

따라서 이미지를 저장하고 완료 콜백을 호출받고 싶다면 콜백을 우선 작성해야 한다. 콜백 함수는 저장하라고 넘겨준 이미지와, 에러 여부를 판단할 NSError*, 그리고 저장 시에 넘겨준 context 정보를 받게 되므로 다음과 같은 식으로 정의할 수 있다.

-(void) image:(UIImage*) image
     didFinishedSavingWithError:(Error*)error
     contextInfo:(void*)contenxtInfo;

따라서 다음과 같이 사용하여 호출한다.

UIImageWriteToSavedPhotosAlbum(
    theImage, 
    self, 
    @selector(image:didFinishedSavingWithError:contextInfo:), 
    nil
);

Swift 가이드

Swift에서 위의 C함수는 다음의 형태로 브릿징된다.

func UIImageWriteToSavedPhotosAlbum(_ image: UIImage,
                                    _ compeletionTarget: Any?,
                                    _ completionHandler: Selector?,
                                    _ contextInfo: UnsafeMutableRawPointer?)

사용하는 방법 자체는 별반 다르지 않다.

// in view controller class...

func image(_ UIImage, didFinishSavingWith error: NSError?, contextInfo context: UnsafeMutableRawPointer?) { ... }

func saveImage() {
  if let image = self.image {
    UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(_:didFinishSavingWith:context:)))
  }
}

만약 UIImage를 별도의 파일로 저장하려고 한다면, 이미지가 특정한 파일로 표현된 표현형 데이터를 얻고, 이를 파일에 쓰는식으로 처리해야 한다.