UIImage: [Apple] UIImage

J.Noma·2022년 1월 26일
0

iOS : View : UIKit

목록 보기
5/17

Reference


Remind

  • UIImage에는 여러 생성자 옵션이 존재하며 캐싱여부 등이 달라 적절한 선택이 필요하다
  • 모든 포맷을 지원하긴 하지만 PNG/JPEG 포맷을 추천한다 (특히 PNG)
  • UIImage 인스턴스는 immutable하다. 따라서 thread-safe하다
  • Stretchable Image란게 있다

🌀 Overview

🔸 UIImage

image 객체를 통해 모든 종류의 이미지 데이터를 표현할 수 있습니다. 그리고 UIImage class는 기반 플랫폼이 지원하는 모든 이미지 포맷에 대한 이미지 데이터를 다룰 수 있습니다. image 객체 자체는 변경이 불가합니다. 따라서 매번 존재하는 이미지 데이터로부터 새로이 만들어내야 합니다 (disk에 있거나 코드로 직접 만든 이미지 파일 데이터 등). image 객체는 단일 이미지 혹은 애니메이션용으로 여러 이미지를 담을 수도 있습니다

image 객체는 다양한 곳에서 사용될 수 있습니다

  • UIImageView에 할당
  • 버튼, 슬라이더, segmentedControl 등의 system control
  • 이미지를 직접 그려서 view로 전달 혹은 다른 graphics context
  • 이미지 데이터를 요구하는 API로의 전달

🔸 PNG/JPEG 포맷을 추천

비록 image 객체가 기반 플랫폼이 지원하는 모든 이지미 포맷을 지원가능하지만, App에서는 PNGJPEG를 사용하는 것이 추천됩니다. image 객체들은 이 두가지 포맷으로 읽고 표시되는데 최적화되어 있습니다. 또한, 이 포맷들은 다른 대부분의 포맷에 비해 뛰어난 성능을 제공합니다. 무손실 압축 포맷인 PNG가 특히 추천됩니다


🌀 UIImage 생성하기

🔸 용도별 생성자

image 객체를 만드려면 일단 이미 존재하는 이미지 데이터가 있어야 합니다. 빈 이미지를 만들어 그릴 순 없습니다. image 객체를 만드는 다양한 옵션이 존재하며 상황별로 선택하면 됩니다

  • init(named:in:compatibleWith:) / init(named:)
    asset 혹은 main bundle에 있는 파일로부터 이미지를 그릴 때 사용합니다. 이 메서드는 자동으로 이미지 데이터를 캐싱하므로 빈번히 호출될 때 특히나 추천됩니다

  • init(contentsOfFile:) / imageWithContentsOfFile:
    초기 데이터가 bundle에 없는 경우에 사용합니다. 이 메서드는 이미지 데이터를 매번 disk로부터 읽어오기 때문에 반복적으로 로딩하는 경우에는 사용하면 안됩니다

-animatedImage(with:duration:) / animatedImageNamed(_:duration:)
애니메이션 표현을 위해 여러 이미지를 하나의 UIImage로 묶어야 하는 경우에 사용합니다. 이렇게 만들어진 애니메이션 이미지를 UIImageView에 할당하여 애니메이션을 만듭니다

🔸 UIImage를 생성할 수 있는 다양한 소스

UIImage의 다른 메서드들을 통해 Core Graphics 이미지 혹은 직접 만들어낸 이미지 데이터처럼 특정 타입 데이터로부터 애니메이션을 만들 수도 있습니다. 또한 UIKit의 UIGraphicsGetImageFromCurrentImageContext() 함수를 사용하여 그려진 상태의 content로부터 image를 만드는 것도 가능합니다. 이 메서드를 drawing command를 캡쳐하기 위해 사용하는 bitmap기반 graphics contenxt와 함께 사용합니다

🔸 UIImage의 불변성

NOTE
image 객체는 immutable하므로 이미 생성된 후에는 프로퍼티를 변경할 수 없습니다. image의 대부분의 프로퍼티는 이미지 파일/데이터에 들어있는 메타데이터로부터 자동으로 설정됩니다. 또한 이런 불변성은 어떠한 스레드로부터 생성/사용되더라도 안전함을 뜻하기도 합니다

🔸 Asset에 저장된 UIImage

image asset은 App에 이미지를 동봉하는 가장 쉬운 방법입니다. 각 Xcode 프로젝트는 asset 라이브러리를 갖고 있으며 이 라이브러리에 여러 이미지 set을 추가할 수 있습니다. 하나의 이미지 set은 하나의 이미지에 대해 App Usage(플랫폼, compact/regular, scale factor 등)별 variation이 포함됩니다

🔸 유저가 제공하는 UIImage

disk로부터 이미지를 로딩하는 것 외에 유저가 카메라나 photo 라이브러리로부터 이미지를 제공하도록 할 수도 있습니다. image picker는 이미지 선택을 위한 custom UI를 보여줍니다. 유저가 제공하는 이미지에 접근하려면 명시적인 권한승인이 필요합니다


🌀 Defining a Stretchable Image

stretchable 이미지는 underlying 이미지 데이터가 심미적으로 뛰어난 방식으로 복제될 수 있는(?) 영역을 정의하는 이미지를 말합니다. 일반적으로 환경에 따라 늘어나거나 줄어들 수 있는 background를 만들기 위해 사용됩니다

resizableImage(withCapInsets:) 혹은resizableImage(withCapInsets:resizingMode:)를 사용하여 이미지에 inset을 추가함으로써 stretchable 이미지를 정의할 수 있습니다. 이 inset은 image를 2개 이상으로 세분화합니다. 각 inset에 non-zero 값을 명시하여 9개 파트로 나누어진 이미지를 만들어냅니다

각 inset은 주어진 dimension에서 늘어나지 않는 이미지 부분을 정의합니다. top/bottom 영역은 좌우로만 늘어나고(height고정), left/right 영역은 위아래로만 늘어납니다(width고정). 아래 그림은 9개 파트 이미지가 공간을 채우기 위해 어떻게 늘어나는지를 보여줍니다. 이미지의 모서리는 늘어나지 않습니다


🌀 Comparing Images

isEqual() 메서드는 두 이미지가 동일한 이미지 데이터를 가지는지 판단할 수 있는 유일한 방법입니다. image 객체는 동일한 이미지 데이터로부터 초기화되더라도 서로 다를 수 있습니다. image 객체들 간 동등성(equality)을 비교하려면 isEqual()이 유일한 방법입니다. 이 메서드는 실제 이미지 데이터를 비교합니다

let image1 = UIImage(named: "MyImage")
let image2 = UIImage(named: "MyImage") 
if image1 != nil && image1!.isEqual(image2) {
    // Correct. This technique compares the image data correctly.
} 
if image1 == image2 {
    // Incorrect! Direct object comparisons may not work.
}

🌀 Accessing the Image Data

image 객체는 underlying 이미지 데이터로의 직접적인 접근을 제공하지 않습니다. 하지만, 다른 포맷으로 이미지 데이터를 뽑아낼 순 있습니다. 특히, cgImage / ciImage 프로퍼티를 사용하여 Core Grphics / Core Image에 호환되는 이미지 버전을 뽑아낼 수 있습니다. 또한, pngData() / jpegData() 메서드로 PNG/JPEG 포맷의 이미지 데이터를 포함하는 Data 인스턴스를 만들어낼 수 있습니다

profile
노션으로 이사갑니다 https://tungsten-run-778.notion.site/Study-Archive-98e51c3793684d428070695d5722d1fe

0개의 댓글