Core Graphics를 사용한 이미지 리사이징: Core Graphics 라이브러리를 사용하여 고급 이미지 처리 기법.

작성일 :

Core Graphics를 사용한 이미지 리사이징

Core Graphics는 iOS와 macOS 앱에서 주로 사용되는 저수준 그래픽 렌더링 API입니다. 이 글에서는 Swift 언어를 사용하여 Core Graphics를 통해 이미지 리사이징을 수행하는 방법을 알아보겠습니다. 이미지 리사이징은 다양한 해상도와 크기를 지원하는 앱에서 매우 중요한 기능입니다. 이번 글에서는 기본적인 리사이징 개념부터 고급 처리 기법까지 다룹니다.

Core Graphics와 UIImage의 기본 개념

Core Graphics는 저수준 API로서 이미지를 직접 다루기 위해 CGImage 객체를 사용합니다. 반면 UIImage는 iOS에서 이미지를 간편하게 관리할 수 있도록 해주는 고수준 객체입니다. 이미지를 리사이징하려면 두 클래스의 상호작용이 필요합니다.

먼저 기본 개념을 이해하는 것이 중요합니다. CGContext, CGImage, 그리고 UIImage의 상호작용을 통해 이미지를 처리할 수 있습니다. 다음 코드는 UIImageCGImage로 변환 후 다시 UIImage로 변환하는 과정을 보여줍니다.

swift
import UIKit
import CoreGraphics

if let image = UIImage(named: "example") {
    guard let cgImage = image.cgImage else { return }

    let context = CGContext(data: nil, width: cgImage.width, height: cgImage.height, bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: cgImage.bytesPerRow, space: cgImage.colorSpace ?? CGColorSpace(name: CGColorSpace.sRGB)!, bitmapInfo: cgImage.bitmapInfo.rawValue)

    context?.draw(cgImage, in: CGRect(x: 0, y: 0, width: cgImage.width, height: cgImage.height))

    if let newCgImage = context?.makeImage() {
        let resizedImage = UIImage(cgImage: newCgImage)
        // resizedImage 사용
    }
}

이미지 리사이징 과정

이미지를 리사이징하는 과정은 다음 순서로 이루어집니다:

  1. 원본 이미지를 CGImage로 변환
  2. 새로운 크기로 CGContext 생성
  3. 원본 이미지를 새 CGContext에 맞춰 그리기
  4. 리사이징된 이미지를 CGImage로 생성
  5. CGImageUIImage로 변환

아래 코드는 이미지를 리사이징하는 구체적인 방법을 보여줍니다.

swift
import UIKit
import CoreGraphics

func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage? {
    let size = image.size

    let widthRatio  = targetSize.width  / size.width
    let heightRatio = targetSize.height / size.height

    // Aspect Ratio를 유지하며 새로운 크기 계산
    var newSize: CGSize
    if(widthRatio > heightRatio) {
        newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
    } else {
        newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
    }

    let rect = CGRect(origin: .zero, size: newSize)

    // 새로운 컨텍스트 생성
    UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
    defer { UIGraphicsEndImageContext() }

    image.draw(in: rect)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()

    return newImage
}

위 함수에서 UIGraphicsBeginImageContextWithOptions 함수를 사용하여 새로운 컨텍스트를 생성하고, 주어진 크기에 맞게 이미지를 그립니다. UIGraphicsGetImageFromCurrentImageContext 함수는 새로 생성된 이미지를 반환합니다.

고급 이미지 처리 기법

단순한 리사이징을 넘어서, 이미지 품질을 유지하거나 향상시키기 위해 고급 기법들이 사용됩니다. 안티앨리어싱과 필터링은 대표적인 예입니다. 아래 코드는 안티앨리어싱을 적용하여 이미지를 리사이징하는 예제입니다.

swift
import UIKit
import CoreGraphics

func resizeImageWithAntialiasing(image: UIImage, targetSize: CGSize) -> UIImage? {
    guard let cgImage = image.cgImage else { return nil }

    let width = Int(targetSize.width)
    let height = Int(targetSize.height)

    let bitsPerComponent = cgImage.bitsPerComponent
    let bytesPerRow = 0
    let colorSpace = cgImage.colorSpace
    let bitmapInfo = cgImage.bitmapInfo

    guard let context = CGContext(
        data: nil,
        width: width,
        height: height,
        bitsPerComponent: bitsPerComponent,
        bytesPerRow: bytesPerRow,
        space: colorSpace!,
        bitmapInfo: bitmapInfo.rawValue
    ) else { return nil }

    context.interpolationQuality = .high
    context.draw(cgImage, in: CGRect(origin: .zero, size: targetSize))

    guard let resizedCgImage = context.makeImage() else { return nil }

    return UIImage(cgImage: resizedCgImage)
}

위 코드에서 context.interpolationQuality 속성을 .high로 설정하여 고품질의 리사이징을 할 수 있습니다. CGContext의 매개변수를 세밀하게 조절함으로써 원하는 결과를 얻을 수 있습니다.

결론

이미지를 리사이징하는 것은 간단해 보일 수 있지만, 실제로는 여러 가지 고려사항이 있는 작업입니다. Swift와 Core Graphics를 통해 다양한 크기와 해상도를 지원하는 이미지 리사이징을 수행할 수 있습니다. 고급 기법을 활용하면 품질을 유지하면서도 성능을 저해하지 않는 최적의 이미지를 만들 수 있습니다.