【问题标题】:Swift Cannot remove CIFIlter from UIImageSwift 无法从 UIImage 中删除 CIFIlter
【发布时间】:2017-01-04 10:57:26
【问题描述】:

现在已经在 swift 上工作了一段时间,但在处理这个 Core Image Framework 时遇到了麻烦。我能够成功地在图像上创建 CIFilter,但是我不确定如何删除它。图像放置在类似于 snapchat 相机屏幕的 UIView 上,然后有一个 imageview,它是预览图像的 uiview 的子视图。顺便说一句,同时使用最新版本的 Xcode 和 iOS。

这是应用黑白滤镜时的代码:

@IBAction func BW_Flt_Bt_Tapped(sender: UIButton) {
    let beginImage = CIImage(image: imagePreview.image!)
    let ciContext = CIContext(options: nil)
    let filter = CIFilter(name: "CIPhotoEffectNoir")
    var imgOrientation = imagePreview.image!.imageOrientation
    var imgScale = imagePreview.image?.scale
    filter!.setDefaults()
    filter!.setValue(beginImage, forKey: kCIInputImageKey)
    let filteredImageData = filter!.valueForKey(kCIOutputImageKey) as! CIImage
    let filteredImageRef = ciContext.createCGImage(filteredImageData, fromRect: filteredImageData.extent)
    imagePreview.image = UIImage(CGImage: filteredImageRef, scale: 1.0, orientation: UIImageOrientation.Right)
    self.orgImgBt.hidden = false
    self.orgImgL.hidden = false
    BWFlt.hidden = true
    BWLbl.hidden = true





}

-imagePreview 是 UIView 的子视图

接下来是我如何将图像改回来的代码

@IBAction func orgImgPressed(sender: UIButton) {
     self.imagePreview.image = self.selctedImage
    orgImgBt.hidden = true
    orgImgL.hidden = true
   `enter code here` BWFlt.hidden = false
    `enter code here`BWLbl.hidden = false


            print("button was pressed")
        }

如果有人有任何建议,我将非常感激,谢谢!

【问题讨论】:

  • 什么是self.selectedImage?

标签: ios swift uiview cifilter ciimage


【解决方案1】:

您可以通过将先前的值保留在变量中来实现此目的,或者如果您有多个过滤器将这些值保留在字典中。当您应用新过滤器或更改现有过滤器的值时,只需将该值替换为新值并将所有值应用于原始 CIImage

例如,

    var allFilters = [String: [String: Any]]()
    var currentImage: CIImage!
    let kCIColorControls = "CIColorControls"

    override func viewDidLoad() {
        super.viewDidLoad()
        currentImage = CIImage(image: self.originalImage!)
    }

    func applyAvailableFilters() {
            if self.allFilters.count > 0 {            
                DispatchQueue.global(qos: .background).async {
                    var outputImage: CIImage!

                    self.blurFilter = CIFilter.init(name: "CIGaussianBlur")
                    self.brightnessFilter = CIFilter.init(name: "CIColorControls")
                    self.cropFilter = CIFilter.init(name: "CICrop")

                    if let blurProperty = self.allFilters[self.kCIGaussianBlur]?.first {
                        self.blurFilter.setValue(blurProperty.value, forKey: blurProperty.key)
                                                self.blurFilter.setValue(self.currentImage, forKey: kCIInputImageKey)
                        outputImage = self.blurFilter.outputImage
                    }

                    if let brightnessProperty = self.allFilters[self.kCIColorControls]?.first {
                        self.brightnessFilter.setValue(brightnessProperty.value, forKey: brightnessProperty.key)
                        if let outputImage = self.blurFilter.outputImage {
                            self.brightnessFilter.setValue(outputImage, forKey: kCIInputImageKey)
                        } else {
                            self.brightnessFilter.setValue(self.currentImage, forKey: kCIInputImageKey)
                        }
                        outputImage = self.brightnessFilter.outputImage
                    }

                    if let cropProperty = self.allFilters[self.kCICrop]?.first {
                        self.cropFilter.setValue(cropProperty.value, forKey: cropProperty.key)
                        if let outputImage = self.brightnessFilter.outputImage {
                            self.cropFilter.setValue(outputImage, forKey: kCIInputImageKey)
                        } else if let outputImage = self.blurFilter.outputImage {
                            self.cropFilter.setValue(outputImage, forKey: kCIInputImageKey)
                        } else {
                            self.cropFilter.setValue(self.currentImage, forKey: kCIInputImageKey)
                        }
                        outputImage = self.cropFilter.outputImage
                    }

                    if let image = outputImage {
                        let openGLContext = EAGLContext(api: .openGLES2)
                        let context = CIContext(eaglContext: openGLContext!)
                        if let cgimg = context.createCGImage(image, from: image.extent) {
                            let processedImage = UIImage(cgImage: cgimg)
                            DispatchQueue.main.async {
                                self.imageView.image = processedImage
                            }
                        }
                    } else {
                        DispatchQueue.main.async {
                            self.imageView.image = self.selectedImage
                        }
                    }
                }
            } else {
                DispatchQueue.main.async {
                    self.imageView.image = self.selectedImage
                }
            }
        }

然后像这样应用您的过滤器(模糊过滤器)

@IBAction func sliderValueChanged(_ sender: UISlider) {
      if sender.value == 0 {
            _ = allFilters.removeValue(forKey: kCIGaussianBlur)
        } else {
            allFilters[kCIGaussianBlur] = [kCIInputRadiusKey: sender.value]
        }
        if allFilters[kCICrop]?.first == nil {
            allFilters[kCICrop] = ["inputRectangle": CIVector(cgRect: self.currentImage.extent)]
        }
        applyAvailableFilters()
}

【讨论】:

    【解决方案2】:

    您可能应该持有对原始图像的引用,而不仅仅是将过滤器应用于UIImageView 中当前显示的任何图像,因为您应用过滤器然后将输出图像设置为UIImageView 并具有不是检索输入图像的方法。另一种选择是保留对CIFilter 的引用。为此,您应该声明一个属性:

    let noirFilter = CIFilter(name: "CIPhotoEffectNoir")!
    

    然后您可以在应用过滤器中使用此过滤器并恢复为原始方法。

    @IBAction func BW_Flt_Bt_Tapped(sender: UIButton) {
    
        let beginImage = CIImage(image: imagePreview.image!)
        noirFilter.setValue(beginImage, forKey: kCIInputImageKey)
        let filteredImage = noirFilter.valueForKey(kCIOutputImageKey) as! CIImage
        imagePreview.image = UIImage(CIImage: filteredImage)
    
        self.orgImgBt.hidden = false
        self.orgImgL.hidden = false
        BWFlt.hidden = true
        BWLbl.hidden = true
    }
    
    @IBAction func orgImgPressed(sender: UIButton) {
    
        let inputImage = noirFilter.valueForKey(kCIInputImageKey) as! CIImage
        imagePreview.image = UIImage(CIImage: inputImage)
    
        orgImgBt.hidden = true
        orgImgL.hidden = true
       `enter code here` BWFlt.hidden = false
       `enter code here`BWLbl.hidden = false
    
    
        print("button was pressed")
    }
    

    或者更理想的是:

    @IBAction func orgImgPressed(sender: UIButton) {
    
        imagePreview.image = self.currentInputImage
    
        orgImgBt.hidden = true
        orgImgL.hidden = true
       `enter code here` BWFlt.hidden = false
       `enter code here`BWLbl.hidden = false
    
    
        print("button was pressed")
    }
    

    其中currentInputImage 是对您应用过滤器的UIImage 的引用。

    【讨论】:

    • 这确实给了我想要的图像,但是它被旋转并且比原始图像小,关于如何纠正它的任何建议?
    • 您是否尝试使用UIImage(CIImage:, scale:, orientation:) 而不是UIImage(CIImage: )?
    猜你喜欢
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多