관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 1. 이미지 리사이징 - ImageIO, ImageSource를 활용한 이미지 리사이징 개념 (CGImageSourceCreateThumbnailAtIndex, "Terminated due to memory") 본문

iOS 응용 (swift)

[iOS - swift] 1. 이미지 리사이징 - ImageIO, ImageSource를 활용한 이미지 리사이징 개념 (CGImageSourceCreateThumbnailAtIndex, "Terminated due to memory")

jake-kim 2023. 11. 21. 01:47

1. 이미지 리사이징 - ImageIO, ImageSource를 활용한 이미지 리사이징 개념 (CGImageSourceCreateThumbnailAtIndex, "Terminated due to memory")

2. 이미지 리사이징 - ImageIO, ImageSource를 활용한 이미지 리사이징 구현 (CGImageSourceCreateThumbnailAtIndex)

3. 이미지 리사이징 - CGImageSourceCreateThumbnailAtIndex와 이미지 회전 처리 옵션 (#CGDictionary)

이미지 리사이징 (다운 샘플링)

  • 보통 이미지 리사이징을 할 때 가장 단순하게 수행하는 방법은 UIGraphics를 사용하는 방법
    • UIGraphics를 사용한 이미지 리사이징 자세한 개념은 이전 포스팅 글 참고
extension UIImage {
    func resize(to size: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        defer { UIGraphicsEndImageContext() }
        draw(in: CGRect(origin: .zero, size: size))
        return UIGraphicsGetImageFromCurrentImageContext() ?? self
    }
}

 

  • 하지만 이렇게 리사이징을 하면 메모리 공간을 비효율을적으로 사용하여 10000 * 10000 해상도쯤 되고, HEIF 포멧의 6mb 의 이미지 5개를 메인 스레드에서 순서대로 처리해도 메모리가 부족하여 크래시가 발생 ("Terminated due to memory") 
  • UIGraphicsBegin...도 있지만 여기서 iOS12부터 좀 더 개선된 UIGraphicsImageRenderer로도 이미지 리사이징 사용 가능
let render = UIGraphicsImageRenderer(size: size)
return render.image { context in
    draw(in: CGRect(origin: .zero, size: size))
}
  • 아래에서 알아볼 ImageIO, ImageSource를 사용하면 메모리 사용량은 75% 줄어들고 UIGraphic를 사용한것보다 성능 50% 증가

ImageIO, ImageSource 개념

  • ImageIO는 file에서부터 I/O를 시도하고, ImageSource 이 이미지 스트림을 통해 이미지를 read하거나 write하는 방식
  • 주로 이미지 파일 형식 간 변환 및 메타데이터 작업에 사용

https://developer.apple.com/documentation/imageio

  • 문서를 훑어보아도 한번에 Metadata에 관한 클래스를 많이 가지고 있음

  • 여기서 CGImageSource를 사용하여 리사이징이 가능

CGImageSource

  • CGImageSource 클래스는 이미지 파일이나 데이터 소스에서 이미지를 생성하는 데 사용
  • 이미지 파일에서 메타데이터를 추출하거나 이미지 프레임을 반복하여 접근하는 데 유용

https://developer.apple.com/documentation/imageio/cgimagesource

  • CGImageSource를 사용하면 이곳에서 Thumbnail 이미지를 뽑아낼 수 있는데 이를 통해서 이미지 리사이징이 가능

  • 이 함수의 결과는 CGImage이며, CGImageSource는 이미지를 여러개 가지고 있을 수 있으므로 이 이미지 중 원하는 곳의 index를 같이 주입하여 사용

  • WWDC 2018 자료에 의하면, UIGraphicsImageRenderer을 사용한 것보다 메모리 사용량에 있어서 75% 적고, 성능도 50% 향상

(75% 적은 메모리 사용)

https://developer.apple.com/videos/play/wwdc2018/416

 

(50% 빠른 속도)

https://developer.apple.com/videos/play/wwdc2018/416

 

(본격적인 리사이징 구현은 다음 포스팅 글에서 계속...)

 

* 전체 코드: https://github.com/JK0369/ExImageResizing

* 참고

- https://developer.apple.com/documentation/imageio

- https://developer.apple.com/documentation/uikit/uigraphicsimagerenderer

- https://developer.apple.com/videos/play/wwdc2018/416

Comments