일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 야곰아카데미
- xcode
- View Life Cycle
- 독서후기
- viewcontroller
- mvvm
- Navigation
- NotificationCenter
- 아이폰
- @available
- contentInset
- Failed to register bundle identifier
- Codegen
- SWIFTUI
- 부트캠프
- Mock
- 스위프트
- human interface guidelines
- Structures and Classes
- 독후감
- IOS
- roundingMode
- SWIFT
- 책후기
- UIResponder
- NumberFormatter
- Info.plist
- delegation
- Modality
- 스타트업주니어로살아남기
- Today
- Total
호댕의 iOS 개발
[iOS] 이미지를 받고, 이미지의 크기를 크롭하기 본문
앱을 사용하다 보면 앱에 필요한 이미지를 업로드를 올릴 일이 발생한다.
흔히 사용하는 카카오톡에서도 그렇고 당근마켓에 팔 물건을 올리기 위해서도 앱에 사진을 올려야 한다.
그렇다면 이럴 때는 뭘 사용해서 사용자가 이미지를 올릴 수 있도록 해야 할까?
일단 이미지를 올릴 수 있도록 하는 것부터 알아보자.
UIImagePickerController
일단 사진첩이나 직접 찍은 사진의 이미지를 불러올 수 있도록 하는 것은 UIImagePickerController를 활용할 수 있다.
A view controller that manages the system interfaces for taking pictures, recording movies, and choosing items from the user's media library.
공식문서에선 UIImagePickerController를 위와 같이 설명하고 있다. 즉, 사진이나 영상을 찍고 사용자의 미디어 라이브러리에서 item을 선택하기 위해 시스템 인터페이스를 관리하는 뷰 컨트롤러라고 소개하고 있다.
ViewController인 만큼 UIKit을 import해야 사용할 수 있다.
또한 image picker의 경우 UIImagePickerController에서 미리 정해놓은 SourceType에 의해 결정된다.
- UIImagePickerController.SourceType.camera : 사진이나 영상을 찍을 인터페이스를 제공한다.
- UIImagePickerController.SourceType.photoLibrary or .savedPhotoAlbum : 저장된 사진이나 영상을 고를 수 있는 인터페이스를 제공한다.
만약 photoLibrary를 선택한다면 다음과 같이 앨범으로 바로 접근할 수 있다.
만약 이미지를 선택하고 어떤 영역을 선택할지 사용자가 고를 수 있도록 하기 위해선 allowsEditing 프로퍼티를 true로 주면 된다.
또한 특정 버튼을 눌렀을 때 이미지를 선택할 수 있도록 앨범으로 가기를 원한다면 특정 버튼에 addTarget을 만들어주고 selector로 objc 메서드를 넣어주면 된다.
button.addTarget(self, action: #selector(presentImagePicker), for: .touchUpInside)
@objc private func presentImagePicker() {
present(imagePickerController, animated: true, completion: nil)
}
아이패드에선 imagePicker가 어떻게 나와야 하는지를 정해두고 있다.
- Camera: 풀스크린을 사용
- Photo Library: 반드시 popover를 사용해야 함
- Saved Photo Album: 반드시 popover를 사용해야 함
또한 ImagePicker를 사용하려면 반드시 UIImagePickerControllerDelegate를 준수해야 한다.
여기에는 imagePickerController(_:didFinishPickingMediaWithInfo:) 메서드를 사용할 수 있다.
이름에서도 볼 수 있듯 미디어를 선택하는 것이 끝났을 때 사용할 수 있는 메서드이다.
매개변수를 자세히 살펴보면 다음과 같다.
- picker: image picker 인터페이스를 관리하는 controller 객체이다. 즉 UIImagePickerController이다.
- info: 원본 이미지와 편집된 이미지가 포함된 Dictionary이다. 관련된 편진 정보도 존재하며 key들은 UIImagePickerController.InfoKey에 존재한다.
- cropRect: 원본 이미지를 사각형으로 크롭된 이미지
- editedImage: 사용자에 의해 수정된 이미지
- imageURL: 이미지 파일의 URL
- livePhoto
- mediaMetadata
- mediaType
- mediaURL
- originalImage: 수정되지 않은 원본 이미지
또한 picker를 종료하기 위해선 dismiss(animated:completion:) 메서드를 사용하면 된다.
이미지의 크기 조절
그럼 이미지의 크기는 어떻게 자를까?
물론 allowEditing 프로퍼티를 통해 사용자가 자를 수 있도록 할 수 있지만 만약 항상 일정한 크기로 이미지를 처리해주고 싶다면 따로 이미지를 잘라주는 메서드를 작성해야 할 것이다.
만약 항상 이미지를 정사각형으로 잘라야 하는 경우로 생각해보자.
그럼 위에 작성했던 imagePickerController(_:didFinishPickingMediaWithInfo:) 메서드에서 조건을 추가해준다.
let isSquare = newImage.size.width == newImage.size.height
if isSquare == false {
if let squareImage = cropSquare(newImage) {
newImage = squareImage
}
}
이렇게 되면 image의 width와 height가 동일하지 않는 경우 cropSquare라는 메서드를 호출하게 된다.
private func cropSquare(_ image: UIImage) -> UIImage? {
let imageSize = image.size
let shortLength = imageSize.width < imageSize.height ? imageSize.width : imageSize.height
let origin = CGPoint(
x: imageSize.width / 2 - shortLength / 2,
y: imageSize.height / 2 - shortLength / 2
)
let size = CGSize(width: shortLength, height: shortLength)
let square = CGRect(origin: origin, size: size)
guard let squareImage = image.cgImage?.cropping(to: square) else {
return nil
}
return UIImage(cgImage: squareImage)
}
@IBAction func tapBackground(_ sender: UITapGestureRecognizer) {
view.endEditing(true)
}
일단 정사각형으로 자르기 위해선 이미지를 짧은 쪽의 길이에 맞춰 크기를 조절해야 한다. 따라서 먼저 image의 짧은 쪽의 길이를 구한다.
그리고 이미지의 정중앙으로 크롭을 해야하기 때문에 CGPoint를 수정해줘야 한다.
빨간 색 직사각형을 원본 사진이라 생각하고 파란색 테두리의 정사각형을 수정해야 할 이미지라고 생각하자.
그럼 원래 (0, 0)으로 빨간색 직사각형 좌측 상단의 꼭지점이 origin으로 되어 있었는데 이를 사진에 표시된 곳으로 옮겨야 한다. 따라서 위 코드처럼 origin을 옮겨줬다.
그럼 사이즈와 origin 모두 정해졌기 때문에 CGRect의 이니셜라이저 중 init(origin: CGPoint, size: CGSize)를 사용하여 사각형을 생성해야 한다.
또한 이를 CGImage의 인스턴스 메서드인 cropping(to:)를 통해 잘라줘야 한다.
이렇게 해주면 원하는 범위로 이미지를 잘라줄 수 있다.
'Software Engineering > iOS' 카테고리의 다른 글
[iOS] Keychain (0) | 2022.01.23 |
---|---|
[iOS] 이미지의 크기 자체를 줄이고 싶다면? (0) | 2022.01.22 |
[iOS] FileManager를 통해 파일을 생성해보자. (0) | 2022.01.10 |
[라이브러리] SwiftLint를 사용해봅시다~ (1) | 2022.01.08 |
[iOS] hitTest와 responderChain (0) | 2022.01.02 |