관리 메뉴

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

[iOS - swift] UIImage 리사이징 방법 (줄였을때 흐려보이는 이미지 현상 해결 방법, 고품질로 리사이징 방법, UIGraphicsBeginImageContextWithOptions 개념) 본문

iOS 응용 (swift)

[iOS - swift] UIImage 리사이징 방법 (줄였을때 흐려보이는 이미지 현상 해결 방법, 고품질로 리사이징 방법, UIGraphicsBeginImageContextWithOptions 개념)

jake-kim 2023. 4. 5. 01:39

이미지 리사이징 방법

  • UIGraphicsBeginImageContextWithOptions를 사용하여 비트맵 이미지 콘텍스트를 생성
  • 비트맵 이미지 콘텍스트를 사용하여 이미지를 그리거나 크기를 조정하는 것

UIGraphics의 context 개념

  • 비트맵 이미지 콘텍스트는 픽셀 기반으로 그림을 그릴 수 있는 인스턴스를 의미
  • 콘텍스트에는 내부적으로 픽셀을 가지고 있고 이 픽셀은 색상 정보를 저장하고 있으며, 그리고 싶은 이미지를 구성
  • UIGraphicsBeginImageContextWithOptions()를 사용하면 현재 화면과 동일한 특성을 가지는 콘텍스트 인스턴스 획득이 가능
  • 콘텍스트로 리사이징 방법
    • UIGraphicsBeginImageContextWithOptions()로 콘텍스트 획득
    • 콘텍스트로 리사이징 수행
    • 이미지를 그림
    • UIGraphicsGetImageFromCurrentImageContext()를 통해 위에서 그린 이미지 획득

리사이징 구현

  • 목표: 아래 이미지를 흐릿하지 않게 이미지를 줄여서 크기를 줄이기 (단, autolayout으로 width, height 값을 고정하는 방법을 사용하지 않음)

  • UIImage에 extension으로 reisize(targetSize:) 메소드 선언
extension UIImage {
    func resize(targetSize: CGSize) -> UIImage? {
 	}   
}
  • 1. context를 획득 (사이즈, 투명도, scale 입력)
    • UIGraphicsBeginImageContextWithOptions 파라미터: (크기, 투명도 적용 여부, scale)
    • scale의 값이 0이면 현재 화면 기준으로 scale을 잡고, sclae의 값이 1이면 self(이미지) 크기 기준으로 설정
    • 만약 scale의 값을 1로하면 품질이 많이 저하되므로 웬만하면 0으로할것
UIGraphicsBeginImageContextWithOptions(targetSize, true, 0)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
context.interpolationQuality = .high
scale = 1 scale = 0
  • 2. 그리기
let newRect = CGRect(x: 0, y: 0, width: targetSize.width, height: targetSize.height)
draw(in: newRect)
  • 3. 그려진 이미지 가져오기
let newImage = UIGraphicsGetImageFromCurrentImageContext()
  • 4. context 종료
UIGraphicsEndImageContext()

(resize 전체 코드)

extension UIImage {
    func resize(targetSize: CGSize, opaque: Bool = false) -> UIImage? {
        // 1. context를 획득 (사이즈, 투명도, scale 입력)
        // scale의 값이 0이면 현재 화면 기준으로 scale을 잡고, sclae의 값이 1이면 self(이미지) 크기 기준으로 설정
        UIGraphicsBeginImageContextWithOptions(targetSize, opaque, 0)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        context.interpolationQuality = .high
        
        // 2. 그리기
        let newRect = CGRect(x: 0, y: 0, width: targetSize.width, height: targetSize.height)
        draw(in: newRect)
        
        // 3. 그려진 이미지 가져오기
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        
        // 4. context 종료
        UIGraphicsEndImageContext()
        return newImage
    }
}
  • 사용하는쪽 코드
private let someImageView: UIImageView = {
    let view = UIImageView()
    let resizedImage = UIImage(named: "img")?.resize(targetSize: .init(width: 200, height: 200))
    view.image = resizedImage
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()

 

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

* 참고

https://stackoverflow.com/questions/2658738/the-simplest-way-to-resize-an-uiimage

https://developer.apple.com/documentation/uikit/1623912-uigraphicsbeginimagecontextwitho

https://developer.apple.com/documentation/uikit/1623924-uigraphicsgetimagefromcurrentima

Comments