iOS - сохранить исходное изображение при создании цикла Core Image Filters - PullRequest
0 голосов
/ 10 сентября 2018

Я следовал этим 2 урокам tutsplus и appcoda

У меня есть изображение внутри vc1, которое я передаю vc2.vc2 имеет два imageViews: originalImageView, который показывает исходное изображение из vc1 и filteredImageView, который показывает новое изображение с примененными основными фильтрами изображений.filteredImageView привязан поверх originalImageView

У меня также есть scrollView, в котором я создаю фильтры coreImage с кнопками, после нажатия кнопки новый фильтр применяется, и отфильтрованное изображение теперь отображается внутриfilteredImageView, который скрывает originalImageView, поскольку он находится под ним.

Как только пользователь нажимает любую из кнопок, которые содержат фильтр, он не может вернуться к исходному изображению.

Как создать кнопку, которая показывает исходное изображение внутри scrollView, которое соответствует всем отфильтрованным изображениям?В идеале это было бы самое первое изображение, так что, как только пользователь нажимает на него, отображается оригинальное изображение

let originalImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.contentMode = .scaleAspectFill
    return imageView
}()

let filteredImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.contentMode = .scaleAspectFill
    return imageView
}()

let scrollView: UIScrollView = {
    let scrollView = UIScrollView()
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.backgroundColor = .black
    return scrollView
}()

var originalImage: UIImage? // set from vc1

let ciFilterNames = [
    "CISharpenLuminance",
    "CIPhotoEffectChrome",
    "CIPhotoEffectFade",
    "CIPhotoEffectInstant",
    "CIPhotoEffectNoir",
    "CIPhotoEffectProcess",
    "CIPhotoEffectTonal",
    "CIPhotoEffectTransfer",
    "CISepiaTone"
]

override func viewDidLoad() {
    super.viewDidLoad()

    createAnchors()

    guard let originalImage = originalImage else { return }

    originaImage.image = originalImage

    var xCoord: CGFloat = 5
    let yCoord: CGFloat = 5
    let buttonWidth:CGFloat = 70
    let buttonHeight: CGFloat = 70
    let gapBetweenButtons: CGFloat = 5

    var itemCount = 0

    for i in 0..<ciFilterNames.count {

        itemCount = i

        let filterButton = UIButton(type: .custom)
        button.frame = CGRect(x: xCoord, y: yCoord, width: buttonWidth, height: buttonHeight)
        filterButton.tag = itemCount
        filterButton.addTarget(self, action: #selector(filterButtonPressed(_:)), for: .touchUpInside)
        filterButton.layer.cornerRadius = 7
        filterButton.clipsToBounds = true

        guard let openGLContext = EAGLContext(api: .openGLES3) else { return }
        let context = CIContext(eaglContext: openGLContext)

        // Create filters for each button
        let coreImage = CIImage(image: originalImage)
        let filter = CIFilter(name: "\(ciFilterNames[i])" )
        filter?.setDefaults()
        filter?.setValue(coreImage, forKey: kCIInputImageKey)

        if ciFilterNames[i] == "CISharpenLuminance" {
            filter?.setValue(0.8, forKey: kCIInputSharpnessKey)
        } else {
            filter?.setValue(1, forKey: kCIInputIntensityKey)
        }

        guard let output = filter?.value(forKey: kCIOutputImageKey) as? CIImage else { return }
        guard let cgimgresult = context.createCGImage(output, from: output.extent) else { return }
        let imageForButton = UIImage(cgImage: cgimgresult)
        filterButton.setBackgroundImage(imageForButton, for: .normal)

        // Add Buttons in the Scroll View
        xCoord += buttonWidth + gapBetweenButtons
        scrollView.addSubview(filterButton)
    }
}

@objc fileprivate func filterButtonPressed(_ sender: UIButton) {

    let button = sender as UIButton

    filteredImageView.image = button.backgroundImage( for: .normal)
}

func createAnchors() {

    view.addSubview(originalImageView)
    view.addSubview(filteredImageView)
    view.addSubview(scrollView)

    originalImageView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    originalImageView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    originalImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
    originalImageView.widthAnchor.constraint(equalToConstant: view.frame.width).isActive = true
    originalImageView.heightAnchor.constraint(equalToConstant: view.frame.width).isActive = true

    filteredImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
    filteredImageView.leadingAnchor.constraint(equalTo: originalImageView.leadingAnchor).isActive = true
    filteredImageView.widthAnchor.constraint(equalTo: originalImageView.widthAnchor).isActive = true
    filteredImageView.heightAnchor.constraint(equalTo: originalImageView.heightAnchor).isActive = true

    scrollView.topAnchor.constraint(equalTo: originalImageView.bottomAnchor, constant: 8).isActive = true
    scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    scrollView.heightAnchor.constraint(equalToConstant: 80).isActive = true
}

rendition

1 Ответ

0 голосов
/ 11 сентября 2018

Вместо scrollView я использовал горизонтальный collectionView, а внутри viewDidLoad 1-го я добавил изображение из vc1 в массив [UIImages], 2-го я перебрал все ciFilterNames и добавил их в массив так же, как я их добавилв scrollView.Сделав это таким образом, я получу оригинальное изображение в качестве первого изображения вместе со всеми отфильтрованными изображениями вместе в collectionVIew.Мне также был нужен только один imageView.

Я добавил два шага в комментарии внутри viewDidLoad

var collectionView: UICollectionView!

let originalImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.contentMode = .scaleAspectFill
    return imageView
}()

var originalImage: UIImage? // set from vc1 or just use your own UIImage(named: "whatever") for this example
var tableData = [UIImage]()
let filterCell = "filterCell"

let ciFilterNames = [
    "CISharpenLuminance",
    "CIPhotoEffectChrome",
    "CIPhotoEffectFade",
    "CIPhotoEffectInstant",
    "CIPhotoEffectNoir",
    "CIPhotoEffectProcess",
    "CIPhotoEffectTonal",
    "CIPhotoEffectTransfer",
    "CISepiaTone"
]

override func viewDidLoad() {
    super.viewDidLoad()

    configureCollectionView()
    createAnchors()

    guard let originalImage = originalImage else { return }

    originaImage.image = originalImage

    // 1. this appends the originalImage as the very first cell
    tableData.append(originaImage)

    guard let openGLContext = EAGLContext(api: .openGLES3) else { return }
    let context = CIContext(eaglContext: openGLContext)

    for i in 0..<ciFilterNames.count {

        let coreImage = CIImage(image: tableData[0])
        let filter = CIFilter(name: "\(ciFilterNames[i])" )
        filter?.setDefaults()
        filter?.setValue(coreImage, forKey: kCIInputImageKey)

        if ciFilterNames[i] == "CISharpenLuminance" {
            filter?.setValue(0.8, forKey: kCIInputSharpnessKey)
        } else if ciFilterNames[i] == "CISepiaTone" {
            filter?.setValue(1, forKey: kCIInputIntensityKey)
        } else {
            filter?.value(forKey: kCIOutputImageKey) as! CIImage
        }

        guard let output = filter?.value(forKey: kCIOutputImageKey) as? CIImage else { return }
        guard let cgimgresult = context.createCGImage(output, from: output.extent) else { return }
        let newImageWithFilterApplied = UIImage(cgImage: cgimgresult)

        // 2. after each loop append the newImageWithFilterApplied to the rest of the cells
        tableData.append(newImageWithFilterApplied)
        collectionView.reloadData()
    }
}

func configureCollectionView() {
    let layout = UICollectionViewFlowLayout()
    layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0)
    layout.scrollDirection = .horizontal

    collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
    collectionView.translatesAutoresizingMaskIntoConstraints = false
    collectionView.delegate = self
    collectionView.dataSource = self
    collectionView.alwaysBounceHorizontal = true
    collectionView.backgroundColor = .black
    collectionView.showsHorizontalScrollIndicator = false
    collectionView.register(FilterCell.self, forCellWithReuseIdentifier: filterCell)
}

func createAnchors() {

    view.addSubview(originalImageView)
    view.addSubview(collectionView)

    originalImageView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    originalImageView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    originalImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
    originalImageView.heightAnchor.constraint(equalToConstant: view.frame.width).isActive = true

    collectionView.topAnchor.constraint(equalTo: originalImageView.bottomAnchor, constant: 10).isActive = true
    collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    collectionView.heightAnchor.constraint(equalToConstant: 80).isActive = true
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return tableData.count
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: 80, height: 80)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 10
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: filterCell, for: indexPath) as! FilterCell

    cell.imageView.image = tableData[indexPath.item]

    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    guard let cell = collectionView.cellForItem(at: indexPath) as? FilterCell else { return }
    guard let indexPath = collectionView.indexPath(for: cell) else { return }

    originalImageView.image = tableData[indexPath.item]
}
...