SwiftUI에서 이미지 편집 기능 구현하기

작성일 :

SwiftUI에서 이미지 편집 기능 구현하기

SwiftUI는 애플의 선언적 UI 프레임워크로, 간결하고 효율적으로 사용자 인터페이스를 구현할 수 있게 해줍니다. 이번 글에서는 SwiftUI를 활용해 이미지 편집 기능을 구현하는 방법을 단계별로 설명합니다. 이미지 필터 적용, 크기 조정, 자르기 등의 기본적인 편집 기능을 중심으로 다룹니다.

프로젝트 설정

SwiftUI 프로젝트를 새롭게 시작하려면 Xcode를 엽니다. File > New > Project를 선택한 후, SwiftUI App 템플릿을 사용해 새 프로젝트를 생성합니다. 프로젝트 이름과 저장 위치를 설정한 후, 기본 설정으로 프로젝트를 생성합니다.

필요한 라이브러리 추가

SwiftUI는 기본적으로 여러 기능을 지원하지만, 이미지 편집 기능을 효율적으로 구현하기 위해서는 추가적인 라이브러리가 필요할 수 있습니다. 여기서는 유명한 'Core Image' 라이브러리를 사용합니다. CoreImage는 애플의 기본 이미지 처리 라이브러리로, 다양한 이미지 필터와 변환 기능을 제공합니다.

swift
import SwiftUI
import CoreImage
import CoreImage.CIFilterBuiltins

기본 구조 설정하기

프로젝트가 생성되면, 먼저 기본적인 UI를 설정합니다. 이미지를 선택하고, 편집할 수 있는 View를 구성합니다. 이를 위해 간단한 SwiftUI View를 작성합니다.

swift
struct ContentView: View {
    @State private var selectedImage: UIImage? = nil
    @State private var processedImage: UIImage? = nil
    @State private var showingImagePicker = false

    var body: some View {
        VStack {
            if let uiImage = selectedImage {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFit()
                    .frame(maxHeight: 300)

                Button(action: applyFilter) {
                    Text("Apply Filter")
                }
            } else {
                Text("Select an Image")
            }

            Button(action: { showingImagePicker = true }) {
                Text("Choose Image")
            }
        }
        .sheet(isPresented: $showingImagePicker) {
            ImagePicker(image: $selectedImage)
        }
    }

    func applyFilter() {
        guard let selectedImage = selectedImage else { return }
        let ciImage = CIImage(image: selectedImage)
        let context = CIContext()

        let sepiaFilter = CIFilter.sepiaTone()
        sepiaFilter.inputImage = ciImage
        sepiaFilter.intensity = 1.0

        guard let outputImage = sepiaFilter.outputImage,
              let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return }

        processedImage = UIImage(cgImage: cgImage)
    }
}

위 코드에서는 간단한 필터 적용 기능을 구현했습니다. 여기서 ImagePicker는 사용자가 이미지를 선택할 수 있도록 하기 위한 별도의 SwiftUI View입니다. 이를 만들기 위해서는 새로운 Swift 파일을 생성하고 다음과 같은 코드를 작성합니다.

swift
import SwiftUI
import UIKit

struct ImagePicker: UIViewControllerRepresentable {
    @Binding var image: UIImage?
    
    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
        let parent: ImagePicker

        init(parent: ImagePicker) {
            self.parent = parent
        }

        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
            if let uiImage = info[.originalImage] as? UIImage {
                parent.image = uiImage
            }

            parent.presentationMode.wrappedValue.dismiss()
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }

    @Environment(".presentationMode") var presentationMode

    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
}

이미지 크기 조정

이미지의 크기를 조정하는 것은 필터를 적용하는 것보다 더 간단합니다. UIImageresizable() 메서드를 사용하여 크기를 조정할 수 있습니다. 다음은 SwiftUI View에서 이미지를 크기 조정하는 예제입니다.

swift
struct ImageResizerView: View {
    @State private var imageSize: CGSize = CGSize(width: 100, height: 100)
    var image: UIImage
    
    var body: some View {
        VStack {
            Image(uiImage: image)
                .resizable()
                .frame(width: imageSize.width, height: imageSize.height)
                .aspectRatio(contentMode: .fit)
                .clipped()

            Slider(value: $imageSize.width, in: 50...300, step: 1) {
                Text("Width")
            }
            Slider(value: $imageSize.height, in: 50...300, step: 1) {
                Text("Height")
            }
        }
    }
}

이미지 자르기

이미지를 자르는 작업은 Core Image로 구성할 수 있지만, 인터페이스 측면에서는 약간 더 복잡합니다. 이미지의 특정 영역을 선택하고 자르기를 수행하는 기능을 추가할 수 있습니다.

swift
struct ImageCropperView: View {
    @State private var cropRect: CGRect = CGRect(x: 0, y: 0, width: 100, height: 100)
    var image: UIImage
    
    var body: some View {
        VStack {
            GeometryReader { geometry in
                Image(uiImage: image)
                    .resizable()
                    .scaledToFit()
                    .overlay(Rectangle().stroke(Color.red, lineWidth: 2).frame(width: cropRect.width, height: cropRect.height).position(x: cropRect.midX, y: cropRect.midY))
            }

            Button(action: cropImage) {
                Text("Crop Image")
            }
        }
    }

    func cropImage() {
        guard let cgImage = image.cgImage?.cropping(to: cropRect) else { return }
        let croppedUIImage = UIImage(cgImage: cgImage)
        // Use cropped UIImage as needed.
    }
}

위 코드는 선택한 이미지의 특정 영역에 빨간색 사각형을 오버레이하고 자르기 기능을 제공합니다. 버튼을 클릭하면 설정된 영역이 잘라집니다.

결론

SwiftUI를 사용하면 이미지 편집 기능을 구현하는 것이 상대적으로 간단해집니다. 이 글에서는 이미지 필터 적용, 크기 조정, 자르기 등을 다루었습니다. 이를 통해 SwiftUI의 선언적 UI의 힘을 활용하여 복잡한 이미지 편집 기능을 효율적으로 구현할 수 있습니다. 추가적인 이미지 편집 기능을 적용하려면 Core Image의 다양한 필터와 변환 기능을 살펴보는 것이 좋습니다.