본문 바로가기
프로그래밍 놀이터/iOS

[iOS Study] 카메라

by 돼지왕 왕돼지 2016. 2. 23.
반응형


 [iOS Study] 카메라


출처 : 아론 힐리가스의 iOS 프로그램


#pragma mark, :, @, @[], @{}, animation, app kill, array, Aspect Fit, availableMediaTypesForSourceType, bounds, cameraOverlayView, CFStringRef, const, containsobject, contentMode, custom class, default value, defaultManager, delegate, dictionary, dismissViewControllerAnimated:completion:, endediting, Framework, Globally Unique Identifier, GUID, IBAction, iboutlet, identifier, imagePickerController:didFinishPickingMediaWithInfo, imagePickerController:didFinishPickingMediaWithInfo:, imagePickerControllerDidCancel, inspector, ios study, ios tutorial, isSourceTypeAvailable, Key, key-value pair, Kill, kUTTypeImage, kUTTypeMovie, kUTTyperImage, literal, lookup table, mac address, mediaTypes, memory kill, MobileCoreServices, modal view controller, NSDictionary, NSFileManager, nsmutabledictionary, nsobject, NSURL, nsuuid, option click, Popover, presentViewController:animated:completion:, removeItemAtPath, resignFirstResponder, setmediatypes, sourceType, target action, textFieldShouldReturn, touch up inside, UIBarButtonItem, UIControl, UIImagePickerController, UIImagePickerControllerDelegate, UIImagePickerControllerMediaURL, UIImagePickerControllerSourceTypeCamera, UIImagePickerControllerSourceTypePhotoLibrary, UIImagePickerControllerSourceTypeSavedPhotosAlbum, UIImageView, UINavigationBar, UINavigationControllerDelegate, UISaveVideAtPathToSavedPhotosAlbum, uitoolbar, uivideo, UIVideoAtPathIsCompatibileWithSavedPhotosAlbum, UIViewContentModeScaleToFill, universally unique identifier, UUID, xcode, XIB, [iOS Study] 카메라, __bridge, 가독성, 거터, 경고, 구현, 기본값, 델리게이트, 드래그, 디바이더, 딕셔너리, 라벨, 로우 메모리 경고, 룩업 테이블, 모달 뷰 컨트롤러, 배열, 보조 편집기, 비디오, 빈 원, 사진, 사진 찍기, 상속, 상수, 소스 편집기 점프바, 소유권, 쉼표, 스틸 이미지, 시간, 아론 힐리가스, 앨범, 앨범 선택, 원, 유연한 자료 구조, 이미지, 인덱스, 인스펙터, 인터페이스, 임시 저장 공간, 자료 구조, 전처리기 지시자, 조직화, 종횡비, 중괄호, 중단, 최근 찍은 사진, 축약법, 카메라, 커넥션, 커서, 컨드롤, 콜론, 콤마, 키, 키 값 쌍, 키보드, 타깃-액션, 팝오버, 편집, 프레임워크, 프로토콜, 해제, 헤더 파일


-

UIImageView 는 contentMode 프로퍼티에 따라 이미지를 표시한다.

이 프로퍼티는 이미지뷰의 프레임 안에서 이미지를 어디에 위치시키고 어떻게 크기를 조절할지를 결정한다.

UIImageView 에서 contentMode 의 기본값은 UIViewContentModeScaleToFill 이다.

이 값은 이미지 크기를 이미지뷰의 bounds 와 정확히 일치하게 조절한다.


이미지가 원본과 같은 종횡비로 표시되도록 하려면 Aspect Fit 으로 설정해야 한다.


#pragma mark, :, @, @[], @{}, animation, app kill, array, Aspect Fit, availableMediaTypesForSourceType, bounds, cameraOverlayView, CFStringRef, const, containsobject, contentMode, custom class, default value, defaultManager, delegate, dictionary, dismissViewControllerAnimated:completion:, endediting, Framework, Globally Unique Identifier, GUID, IBAction, iboutlet, identifier, imagePickerController:didFinishPickingMediaWithInfo, imagePickerController:didFinishPickingMediaWithInfo:, imagePickerControllerDidCancel, inspector, ios study, ios tutorial, isSourceTypeAvailable, Key, key-value pair, Kill, kUTTypeImage, kUTTypeMovie, kUTTyperImage, literal, lookup table, mac address, mediaTypes, memory kill, MobileCoreServices, modal view controller, NSDictionary, NSFileManager, nsmutabledictionary, nsobject, NSURL, nsuuid, option click, Popover, presentViewController:animated:completion:, removeItemAtPath, resignFirstResponder, setmediatypes, sourceType, target action, textFieldShouldReturn, touch up inside, UIBarButtonItem, UIControl, UIImagePickerController, UIImagePickerControllerDelegate, UIImagePickerControllerMediaURL, UIImagePickerControllerSourceTypeCamera, UIImagePickerControllerSourceTypePhotoLibrary, UIImagePickerControllerSourceTypeSavedPhotosAlbum, UIImageView, UINavigationBar, UINavigationControllerDelegate, UISaveVideAtPathToSavedPhotosAlbum, uitoolbar, uivideo, UIVideoAtPathIsCompatibileWithSavedPhotosAlbum, UIViewContentModeScaleToFill, universally unique identifier, UUID, xcode, XIB, [iOS Study] 카메라, __bridge, 가독성, 거터, 경고, 구현, 기본값, 델리게이트, 드래그, 디바이더, 딕셔너리, 라벨, 로우 메모리 경고, 룩업 테이블, 모달 뷰 컨트롤러, 배열, 보조 편집기, 비디오, 빈 원, 사진, 사진 찍기, 상속, 상수, 소스 편집기 점프바, 소유권, 쉼표, 스틸 이미지, 시간, 아론 힐리가스, 앨범, 앨범 선택, 원, 유연한 자료 구조, 이미지, 인덱스, 인스펙터, 인터페이스, 임시 저장 공간, 자료 구조, 전처리기 지시자, 조직화, 종횡비, 중괄호, 중단, 최근 찍은 사진, 축약법, 카메라, 커넥션, 커서, 컨드롤, 콜론, 콤마, 키, 키 값 쌍, 키보드, 타깃-액션, 팝오버, 편집, 프레임워크, 프로토콜, 해제, 헤더 파일

-

소스 파일을 옵션 - 클릭 하면 보조 편집기로 소스가 열린다.



-

xib 에서 소스파일로 컨트롤 - 드래그 하면 바로 IBOutlet 이나  IBAction  을 연결할 수 있다.



-

UIToolbar 는 UINavigationBar 와 많은 부분 유사하게 동작한다.

UIBarButtonItem 인스턴스를 툴바에도 추가할 수 있다.

네비게이션바는 바 버튼 아이템을 위해 두 개의 공간을 제공하는 반면,

툴바는 바 버튼 아이템의 배열을 가진다.

툴바에는 화면 크기에 맞는 한 여러 바 버튼 아이템을 가질 수 있다.



-

기본적으로 XIB 파일에서 만들어진 UIToolbar 의 인스턴스는 하나의 UIBarButtonItem 이 따라온다.

바 버튼 아이템을 선택하고 속성 인스펙터를 열어, Identifier 를 Camera 로 변경하면 카메라 아이콘이 나타난다.



-

IBAction 메소드의 거터 영역에는 원이 표시되는데,

XIB 파일에서 액션 메소드가 연결되면 이 원이 채워지고, 빈 원은 연결되지 않음을 이야기한다.



-

XIB 에서 컨트롤 드래그를 통해 아웃렛을 연결하는 중에 실수가 있었다면 xib 을 열고 잘못된 커넥션을 해제해야 한다.

( 커넥션 인스펙터에서 노란 경고 표시를 확인한다. )



-

UIImagePickerController 는 사진을 찍거나 선택하는 기능을 제공하는 controller 이다.

UIImagePickerController 의 인스턴스를 만들 때 sourceType 프로퍼티를 설정해야 한다.

그리고 UIImagePickerController 의 델리게이트도 할당해야 한다.



-

UIImagePickerController 의 sourceType 은 이미지 피커에게 어디서 이미지를 얻을지 알려주는 상수이다.


UIImagePickerControllerSourceTypeCamera     사용자가 새 사진을 찍을 것이다.

UIImagePickerControllerSourceTypePhotoLibrary     사용자에게 앨범을 선택하는 화면과 그 앨범에서 사진을 선택하는 화면이 나타난다.

UIImagePickerControllerSourceTypeSavedPhotosAlbum     사용자가 최근에 찍은 사진을 선택한다.


UIImagePickerControllerSourceTypeCamera 는 카메라가 없는 장치에서는 동작하지 않는다.

따라서 이 타입을 사용하기 전에 UIImagePickerController 클래스에 isSourceTypeAvailable 메시지를 보내 카메라 유무를 확인해야 한다.


+ (BOOL) isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType;



-

UIImagePickerController 인스턴스는 소스 타입 외에 추가로 델리게이트가 필요하다.

사용자가 UIImagePickerController 의 인터페이스에서 이미지를 선택하면, 그 델리게이트에 imagePickerController:didFinishPickingMediaWithInfo: 메시지가 보내진다.

취소 버튼을 누르면 델리게이트는 imagePickerControllerDidCancel: 메시지를 받는다.



-

UIImagePickerController 의 델리게이트를 하기 위해서는 UINavigationControllerDelegate 와 UIImagePickerControllerDelegate 2개의 protocol 을 지정해주어야 한다.

UIImagePickerController 의 delegate 프로퍼티는 실제로 그 상위 클래스인 UINavigationController 로부터 상속된 것이다.

하지만 UIImagePickerController 는 자기 소유의 델리게이트 프로토콜을 가진다.

상속된 delegate 프로퍼티는 UINavigationControllerDelegate 를 따르는 객체를 가리키도록 선언돼 있어 2개 모두 지정해주어야 한다.







-

UIImagePickerController 인스턴스는 모달 방식으로 나타난다.

모달 뷰 컨트롤러(modal view controller)는 그 작업이 끝날 때까지 화면 전체를 사용한다.


뷰 컨트롤러를 모달로 나타내려면 presentViewController:animated:completion: 메시지를 화면에 나타낼 view 의 UIViewController 에 보내야 한다.

나타낼 뷰 컨트롤러를 전달하면 그 뷰 컨트롤러의 뷰가 화면 아래에서 슬라이드하면서 나타날 것이다.


[self presentViewController:imagePicker animated:YES completion:nil];



-

imagePickerController:didFinishPickingMediaWithInfo: 델리게이트 메소드는 사진을 찍거나, 이미지를 선택했을 때 불린다.


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{

     UIImage *image = info[UIImagePickerControllerOriginalImage];

     [self dismissViewControllerAnimated:YES completion:nil];

}



-

로우 메모리 경고가 발생하고 앱의 메모리 공간이 계속 늘어나면 운영체제는 그 앱을 중단시킨다.



-

딕셔너리(dictionary)는 배열과 마찬가지로 컬렉션 객체이다.

딕셔너리에는 변경할 수 없는 버전(NSDictionary)과 변경할 수 있는 버전(NSMutableDictionay)이 있다.


배열은 인덱스로 접근 가능한 객체 포인터들의 순차적 목록이다.

배열에서는 n번째 인덱스에 있는 객체를 요청할 수 있다.


딕셔너리의 객체들은 컬렉션 안에서 순차적이지 않다.

따라서 인덱스로 접근하는 대신에 키(key)를 사용한다.

키는 보통 NSString 인스턴스이다.


딕셔너리에서 각 엔트리는 키-값 쌍(key-value pair)라고 한다.



-

NSDictionary 를 사용하는 가장 많은 예 두 가지는 유연한 자료 구조와 룩업 테이블(lookup table)이다.


일반적으로 모델 객체를 나타내길 원하는 경우, NSObject 의 하위 클래스를 만들고 그 객체를 적절한 인스턴스 변수에 준다.

예를 들어 Person 클래스는 firstName, age 등과 실제 사람이 지닐 수 있는 여러 가지 것들을 인스턴스 변수로 가질 것이다.

NSDictionary 도 모델 객체를 표현하는 데 사용할 수 있다.

사람 클래스 예제에서 firstName, age 그 외 다른 키에 대한 값을 가질 수 있다.


두 방식의 다른 점은 Person 클래스는 Person 이 무엇인지 정확히 정의하기를 요구하고 사람의 구성 요소를 추가, 삭제, 변경할 수 없다는 점이다.

반면에 NSDictionary 를 가지고 "Person" 에 주소를 추가하고 싶다면, 간단히 address 키와 그 값을 추가하면 된다.


모든 객체를 표현하는 데 NSDictionary 의 사용을 지지하는 것은 아니다.

대다수 객체들이 데이터를 저장하고 로드하는 과정에 엄격한 정의와 규칙을 필요로 한다.



-

NSDictionary 는 지정한 옵션에 따라 다른 자료 구조를 가질 수 있는 메소드에 전달되거나 그 메소드에서 반환되는 데이터를 나타내는 데 흔히 사용된다.



-

NSDictionary 의 또 다른 흔한 사용 예로 룩업 테이블을 만드는 것이 있다.



-

딕셔너리를 사용할 때 각 키는 하나의 객체에만 해당된다.

만약 딕셔너리에 이미 존재하는 객체의 키와 동일한 키로 딕셔너리에 객체를 추가하면 이전 객체는 제거된다.

또한 한 키에 여러 객체를 저장하길 원한다면, 객체들을 배열에 담아 그 키의 값으로 딕셔너리에 추가할 수 있다.


딕셔너리도 배열과 마찬가지로 축약법을 사용하여 만들 수 있다.

딕셔너리의 축약법은 대괄호 @[] 를 사용하는 NSArray 와 달리 중괄호 @{} 를 사용한다.

딕셔너리를 축약법으로 초기화할 때 각 키-값 쌍은 쉼표(,) 로 구분된다.

키와 그 값 사이에는 콜론(:) 이 위치한다.


-

딕셔너리의 메모리 관리는 배열과 유사하다는 사실에 주의한다.

딕셔너리에 객체를 추가하면 딕셔너리는 그 객체를 소유하고 객체를 제거하면 소유권을 해제한다.



-

고유한 문자열을 만드는 법 중 하나는 UUID(universally unique identifier) 를 사용하는 것이다.

이것은 GUID(globally unique identifier)라고도 한다.

NSUUID 타입의 객체는 UUID 를 나타낸다.

이 객체는 시간, 카운터, 하드웨어 식별자(대게 무선랜 카드의 MAC 주소)를 사용하여 만든다.



-

UIImageView 는 그 값이 nil 이면 이미지를 표시하지 않는다.



-

사용자가 리턴키를 누를 때 키보드를 닫기 위해서는 textFieldShouldReturn: 델리게이트 메소드를 구현해야 한다.


- (BOOL)textFieldShouldReturn:(UITextField *)textField{

     [textField resignFirstResponder];

     return YES;

}



-

endEditing: 메시지를 view 에 보내서도 키보드를 닫을 수 있다.



-

버튼은 자신의 상위 클래스인 UIControl 에서 타깃-액션 동작을 상속받는다.

View 를 터치했을 때 키보드를 내리고 싶다면,

xib 에서 view 의 custom class 를 UIControl 로 바꿔주고,

IBAction 을 Touch Up Inside 로 연결해서 endEditing:YES 를 호출해주면 된다.



-

UIImagePickerController 는 선택된 이미지를 편집할 수 있는 내장 인터페이스를 가지고 있다.

사용자가 이미지를 편집하고 원본 이미지 대신에 편집된 이미지를 사용할 수 있도록 할 수 있다.



-

UIImagePickerController  는 cameraOverlayView 라는 프로퍼티를 가지고 있다.

이 프로퍼티를 사용하여 UIImagePickerController 에서 이미지 캡쳐 영역에 overlay 를 설정할 수 있다.







-

소스 편집기 점프바는 현재 프로젝트 안에서 정확히 어디 있는지를(또한 주어진 파일에서 커서가 어디에 있는지를) 보여준다.


이 섹션 중 하나를 클릭하면 프로젝트 계층구조에서 그 영역의 팝오버(popover) 메뉴가 나타날 것이다.

이를 통해 프로젝트의 다른 부분으로 쉽게 이동할 수 있다.


팝오버가 보이는 동안 그 목록에서 특정 품목을 찾기 위해 입력을 할 수 있다.

어디에서든 상하 화살표키를 이용해 움직인 후 엔터키를 누르면 코드에서 해당 메소드로 이동할 수 있다.



-

클래스가 길어지면 길어질수록 긴 메소드 목록에 파묻혀 원하는 메소드를 찾기 어려워진다.

이를 해결할 좋은 방법은 #pragma mark 전처리기 지시자를 사용하여 메소드를 조직하는 것이다.


소스코드에 #pragma mark 를 추가하는 것은 코드에 아무런 영향을 미치지 않는다.

하지만 우리가 메소드를 어떻게 조직하길 원하는지 Xcode 가 이해하도록 돕는다.


#pragma mark 에서 두 가지 유용한 것은 디바이더와 라벨이다.


#pragma mark - 는 라벨을 만든다.

#pragma mark My Methods 는 라벨이다.

#pragma mark - My Methods 는 디바이더와 라벨이 합쳐진 형태이다.



-

#pragma mark 지시자를 사용하여 코드를 조직화하도록 강제할 수 있다.

제대로 적용한다면 코드와 가독성이 좋아지고 나중에 다시 작업하기 쉬워질 것이다.

반복적으로 수행하면 코드를 네비게이션하는 데 도움을 주는 좋은 습관이 될 것이다.



-

UIImagePickerController 는 mediaTypes 프로퍼티도 가지고 있다.

mediaType 은 스틸 이미지와 비디오 둘 중 하나이다.

기본적으로 mediaType 배열은 kUTTyperImage 상수 문자열만을 포함한다.

이미지 피커 컨트롤러의 mediaTypes 프로퍼티를 변경하지 않으면, 카메라로 사진만을 찍거나 사진 라이브러리와 사진 앨범에서 이미지만을 표시한다.


비디오를 녹화하거나 디스크에서 비디오를 선택하는 기능을 추가하려면 간단히 kUTTypeMovie 상수 문자열을 mediaTypes 배열에 추가하면 된다.

하지만 모든 장치가 UIimagePickerController 를 통해 비디오를 지원하는 것은 아니다.

isSourceTypeAvailable: 클래스 메소드로 장치에 카메라가 있는지 확인했던 것처럼, 카메라가 있다면 availableMediaTypesForSourceType: 메소드로 비디오를 녹화할 수 있는지 확인할 수 있다.


UIImagePickerController *picker = [[UIImagePickerController alloc] init];

NSArray *availableTypes = [UIImagePickerController     availableMediaTypesForSourceType:UIImagePickerControlelrSourceTypeCamera];

picker.mediaTypes = availableTypes;



-

UIImagePickerController 의 imagePickerController:didFinishPickingMediaWithInfo: 델리게이트 메소드에서 스틸 이미지를 다룰 때 인자로 전달된 info 딕셔너리는 UIImage 객체에 이미지 전체를 포함한다.

하지만 “UIVideo” 라는 클래스는 없다.

(제한된 메모리를 가진 iOS 장비에 한 번에 비디오 전체를 메모리에 올리는 것은 힘든 일이다.)

따라서 녹화된 비디오는 디스크의 임시 디렉터리에 저장된다.

사용자가 비디오 녹화를 마치면 imagePickerController:didFinishPickingMediaWithInfo:  메시지가 이미지 피커 컨트롤러의 델리게이트에 전해진다.

그리고 디스크상의 비디오 경로는 info  딕셔너리에 담겨있다.


NSURL *mediaURL = info[UIImagePickerControllerMediaURL];



-

임시 디렉터리가 비디오를 저장하기에 안전한 곳이 아니라는 것 정도는 알고 있어야 한다.

따라서 비디오를 다른 위치로 옮겨야 한다.


if ( mediaURL ){

     if (UIVideoAtPathIsCompatibileWithSavedPhotosAlbum([mediaURL path]){

          UISaveVideAtPathToSavedPhotosAlbum([mediaURL path], nil, nil, nil);

          [[NSFileManager defaultManager] removeItemAtPath:[mediaURL path] error:nil];

     }

}



-

사용자가 이미지와 비디오 둘 중에 선택하도록 하는 것은 간단하다.

availableMediaTypesForSourceType: 의 반환값을 전달하면 된다.

하지만 비디오만을 허용하는 것은 험난하다.

장치가 비디오를 지원하는지 확인해야 한다.

그리고 mediaTypes 프로퍼티를 비디오 식별자만을 포함하도록 설정해야 한다.


// MobileCoreServices 프레임워크 임포트

NSArray *availableTypes = [UIImagePickerController     availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];

if ([availabelTypes containsObject:(__bridge NSString *)kUTypeMovie]){

     [picker setMediaTypes:@[__bridge NSString *)kUTTypeMovie]];

}


kUTTypeMovie 를 NSString 으로 캐스팅하는 이유는 상수가 다음과 같이 선언되었기 때문이다.


const CFStringRef kUTTypeMovie;


kUTTypeMovie 와 kUTTypeImage 는 MobileCoreServices 라는 다른 프레임워크에 선언되어 정의됐다.

두 상수를 사용하기 위해서는 명시적으로 이 프레임워크를 추가하고 자신의 프로젝트에 그 헤더 파일을 추가해야 한다.









반응형

댓글