问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

使用Swift和UIKit创建图片编辑App

创作时间:
作者:
@小白创作中心

使用Swift和UIKit创建图片编辑App

引用
5
来源
1.
https://www.kodeco.com/18895088-uicollectionview-tutorial-getting-started
2.
https://developer.apple.com/documentation/coreimage/processing_an_image_using_built-in_filters
3.
https://developer.apple.com/tutorials/app-dev-training/adopting-collection-views
4.
https://www.kodeco.com/30195423-core-image-tutorial-getting-started
5.
https://www.hackingwithswift.com/books/ios-swiftui/basic-image-filtering-using-core-image

本篇文章将带你使用Swift和UIKit通过纯代码方式创建一个简单的图片编辑应用程序。这个应用将实现以下功能:

  1. 界面分为上下两部分:上面显示一张预设的图片,下面是一个可以左右滑动的视图,用于展示不同滤镜效果的缩略图。
  2. 点击任一缩略图后,上方的图片将应用对应的滤镜效果。

项目结构

首先,我们需要创建一个UIViewController作为主界面,包含一个UIImageView显示原图,以及一个UICollectionView来展示滤镜缩略图。

import UIKit
import CoreImage

class ImageEditorViewController: UIViewController {
    let imageView = UIImageView()
    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }

    func setupUI() {
        view.addSubview(imageView)
        imageView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            imageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            imageView.heightAnchor.constraint(equalToConstant: 300)
        ])

        imageView.contentMode = .scaleAspectFit
        imageView.image = UIImage(named: "your-image-name")

        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.register(FilterCollectionViewCell.self, forCellWithReuseIdentifier: "FilterCell")
        collectionView.backgroundColor = .white

        view.addSubview(collectionView)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: imageView.bottomAnchor),
            collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            collectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])
    }
}

实现滤镜功能

接下来,我们需要使用Core Image框架来实现滤镜功能。首先定义一组常用的滤镜:

enum FilterType: String {
    case sepiaTone = "CISepiaTone"
    case photoEffectInstant = "CIPhotoEffectInstant"
    case photoEffectNoir = "CIPhotoEffectNoir"
    case photoEffectChrome = "CIPhotoEffectChrome"
    case colorInvert = "CIColorInvert"
    case colorMonochrome = "CIColorMonochrome"
    case colorControls = "CIColorControls"
    case exposureAdjust = "CIExposureAdjust"
    case gammaAdjust = "CIGammaAdjust"
    case hueAdjust = "CIHueAdjust"
    case temperatureAndTint = "CITemperatureAndTint"
    case vibrance = "CIVibrance"
    case whitePointAdjust = "CIWhitePointAdjust"
}

然后,我们需要一个方法来应用滤镜:

func applyFilter(_ filterType: FilterType, to image: UIImage) -> UIImage? {
    guard let ciImage = CIImage(image: image) else { return nil }
    let context = CIContext()

    let filter = CIFilter(name: filterType.rawValue)
    filter?.setValue(ciImage, forKey: kCIInputImageKey)

    if let outputImage = filter?.outputImage {
        if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
            return UIImage(cgImage: cgImage)
        }
    }
    return nil
}

处理用户交互

当用户点击collection view中的cell时,我们需要获取对应的滤镜并应用到原图上:

extension ImageEditorViewController: UICollectionViewDataSource, UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return FilterType.allCases.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FilterCell", for: indexPath) as! FilterCollectionViewCell
        let filterType = FilterType.allCases[indexPath.item]
        cell.filterImageView.image = applyFilter(filterType, to: imageView.image!)
        cell.filterLabel.text = filterType.rawValue
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let filterType = FilterType.allCases[indexPath.item]
        imageView.image = applyFilter(filterType, to: imageView.image!)
    }
}

性能优化

为了提高性能,我们需要在后台队列异步处理滤镜生成,并缓存已生成的缩略图:

var filterCache = [FilterType: UIImage]()

func applyFilter(_ filterType: FilterType, to image: UIImage) -> UIImage? {
    if let cachedImage = filterCache[filterType] {
        return cachedImage
    }

    DispatchQueue.global(qos: .userInitiated).async {
        guard let ciImage = CIImage(image: image) else { return }
        let context = CIContext()

        let filter = CIFilter(name: filterType.rawValue)
        filter?.setValue(ciImage, forKey: kCIInputImageKey)

        if let outputImage = filter?.outputImage {
            if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
                let filteredImage = UIImage(cgImage: cgImage)
                DispatchQueue.main.async {
                    self.filterCache[filterType] = filteredImage
                }
                return filteredImage
            }
        }
    }
    return nil
}

最后

通过以上步骤,我们就完成了一个简单的图片编辑App。这个应用展示了如何使用Swift和UIKit创建自定义界面,并使用Core Image框架实现图片滤镜功能。你可以根据需要添加更多滤镜效果,或者优化用户界面和交互体验。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号