Search code examples
iosswiftuiimagegpuimagecore-image

Why did UIImageWriteToSavedPhotosAlbum save a red image after rendering?


I wrote a code using GPUImage2(https://github.com/BradLarson/GPUImage2).

I confirmed that my code successfully save an image before touching a set button (Rendering a filtered image).

However, my code save a red image (same size, only red filled) after touching a set button.

My App. includes a RenderView IBOutlet and two IBActions (Set Button & Save Button).

Here is my full source code.

How can I successfully save an image after touching a set button?

import UIKit
import GPUImage

class ViewController: UIViewController {
  var inputUIImage = UIImage(named: "testImage.png")
  @IBOutlet weak var renderView: RenderView!
  var pictureInput: PictureInput!
  var filterColorInversion = ColorInversion()

  @IBAction func setButtonDown(_ sender: UIButton) {
     pictureInput = PictureInput(image: inputUIImage!)
     pictureInput --> filterColorInversion --> renderView
    pictureInput.processImage()
  }

  @objc func saveImageFailedCallback(_ image: UIImage, didFinishSavingWith error: NSError?, contextInfo context: UnsafeMutableRawPointer?) {
    print("\(String(describing: error))")
  }

  @IBAction func saveButtonDown(_ sender: UIButton) {
    let outputImage = inputUIImage!.filterWithOperation(filterColorInversion)
    UIImageWriteToSavedPhotosAlbum(outputImage, self, #selector(saveImageFailedCallback(_:didFinishSavingWith:contextInfo:)), nil)
  }

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

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
  }
}

It shows that my code successfully save an image before touching a set button (Rendering a filtered image):

enter image description here

It shows that my code successfully render a filtered image after touching a set button: enter image description here

It shows that my code fails to save a filtered image after touching a set button (but same size and only filled red):

enter image description here


Solution

  • I solved this problem! I added an optional UIImage (tempImage) that is used to save temporarily on the memory. When "saveButtonDown()" is called, I check whether tempImage is nil. If it is nil, I just print an error message (No Image). If it is not nil, it must had been initialized at "setButtonDown()". Here is my full source code. Thank you.

    import UIKit
    import GPUImage
    
    class ViewController: UIViewController {
        var inputUIImage = UIImage(named: "testImage.png")
        @IBOutlet weak var renderView: RenderView!
        var pictureInput: PictureInput!
        var filterColorInversion = ColorInversion()
    
        var tempImage: UIImage?
    
        @IBAction func setButtonDown(_ sender: UIButton) {
            pictureInput = PictureInput(image: inputUIImage!)
    
            tempImage = inputUIImage!.filterWithOperation(filterColorInversion)
    
            pictureInput --> filterColorInversion --> renderView
            pictureInput.processImage()
        }
    
        @objc func saveImageFailedCallback(_ image: UIImage, didFinishSavingWith error: NSError?, contextInfo context: UnsafeMutableRawPointer?) {
            print("\(String(describing: error))")
        }
    
        @IBAction func saveButtonDown(_ sender: UIButton) {
            if (tempImage != nil) {
                UIImageWriteToSavedPhotosAlbum(tempImage!, self, #selector(saveImageFailedCallback(_:didFinishSavingWith:contextInfo:)), nil)
            } else {
                print("No Image")
            }
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    }