Работа с изображениями в Swift (iOS/macOS): полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с изображениями в Swift (iOS/macOS)

В этой статье мы рассмотрим основные подходы и инструменты для работы с изображениями в экосистеме Apple. Вы узнаете, как загружать, отображать, обрабатывать и сохранять изображения с помощью встроенных фреймворков Swift для iOS и macOS. Материал будет полезен как новичкам, так и опытным разработчикам.

Основные фреймворки для работы с изображениями

В Swift существует несколько ключевых фреймворков для работы с графикой:

  • UIKit (iOS) — UIImage, UIImageView
  • AppKit (macOS) — NSImage, NSImageView
  • Core Image — фильтры и обработка
  • Core Graphics — низкоуровневое рисование
  • Metal — GPU-ускорение для сложных операций
  • SwiftUI — декларативный интерфейс с Image

Загрузка и отображение изображений

Рассмотрим базовые примеры для обеих платформ.

iOS (UIKit)

import UIKit

// Загрузка из assets
let image = UIImage(named: "example")

// Загрузка из файла
if let path = Bundle.main.path(forResource: "photo", ofType: "jpg") {
    let imageFromFile = UIImage(contentsOfFile: path)
}

// Отображение в UIImageView
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
imageView.image = image
imageView.contentMode = .scaleAspectFit

macOS (AppKit)

import AppKit

// Загрузка из assets
let image = NSImage(named: "example")

// Загрузка из файла
if let path = Bundle.main.path(forResource: "photo", ofType: "jpg") {
    let imageFromFile = NSImage(contentsOfFile: path)
}

// Отображение в NSImageView
let imageView = NSImageView(frame: NSRect(x: 0, y: 0, width: 200, height: 200))
imageView.image = image
imageView.imageScaling = .scaleProportionallyUpOrDown

SwiftUI (кросс-платформенный)

import SwiftUI

struct ContentView: View {
    var body: some View {
        Image("example")
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(width: 200, height: 200)
    }
}

Обработка изображений с Core Image

Core Image предоставляет более 200 встроенных фильтров для обработки изображений. Вот пример применения сепии:

import CoreImage

func applySepiaFilter(to image: UIImage) -> UIImage? {
    guard let ciImage = CIImage(image: image) else { return nil }
    
    let filter = CIFilter(name: "CISepiaTone")
    filter?.setValue(ciImage, forKey: kCIInputImageKey)
    filter?.setValue(0.8, forKey: kCIInputIntensityKey)
    
    guard let outputImage = filter?.outputImage else { return nil }
    
    let context = CIContext()
    guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return nil }
    
    return UIImage(cgImage: cgImage)
}

Изменение размера и обрезка

Часто требуется изменить размер изображения или обрезать его по центру:

extension UIImage {
    func resized(to targetSize: CGSize) -> UIImage {
        let renderer = UIGraphicsImageRenderer(size: targetSize)
        return renderer.image { _ in
            self.draw(in: CGRect(origin: .zero, size: targetSize))
        }
    }
    
    func croppedToSquare() -> UIImage {
        let side = min(size.width, size.height)
        let x = (size.width - side) / 2
        let y = (size.height - side) / 2
        let cropRect = CGRect(x: x, y: y, width: side, height: side)
        
        guard let cgImage = cgImage?.cropping(to: cropRect) else { return self }
        return UIImage(cgImage: cgImage)
    }
}

Сохранение изображений

Рассмотрим, как сохранить изображение в галерею или в файл:

import Photos

// Сохранение в фотоальбом (iOS)
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)

// Сохранение в файл (iOS/macOS)
func saveImageToDocuments(_ image: UIImage, fileName: String) {
    guard let data = image.jpegData(compressionQuality: 0.8) else { return }
    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    let fileURL = documentsDirectory.appendingPathComponent(fileName)
    
    do {
        try data.write(to: fileURL)
        print("Изображение сохранено: \(fileURL)")
    } catch {
        print("Ошибка сохранения: \(error)")
    }
}

Работа с Core Graphics для продвинутой обработки

Рекомендаций