kCIInputCenterKey崩溃应用于我的imageView内部的图像,该图像位于scrollView中

时间:2017-04-11 22:51:49

标签: ios swift swift3

以下是我试图将CIBumpDistortion应用于我的图片视图中加载的图片的功能:

  @IBAction func filter(_ sender: Any) {

    guard let image = self.imageView.image?.cgImage else { return }



   // let offset = scrollView.contentOffset
    let openGLContext = EAGLContext(api: .openGLES3)
    let context = CIContext(eaglContext: openGLContext!)
    let ciImage = CIImage(cgImage: image)

    let filter = CIFilter(name: "CIBumpDistortion")

    filter?.setValue(ciImage, forKey: kCIInputImageKey)
    //filter?.setValue((x:0, y:0), forKey: kCIInputCenterKey)
    filter?.setValue(300.0, forKey: kCIInputRadiusKey)
    filter?.setValue(5.50, forKey: kCIInputScaleKey)


    if let output = filter?.value(forKey: kCIOutputImageKey) as? CIImage{
        self.imageView.image = UIImage(cgImage: context.createCGImage(output, from: output.extent)!)
    }


}

截至目前,上述与CenterKey合作的作品已被注释掉。它默认并将滤镜应用于图像的左下角。如果我取消注释并尝试在其中放置任何值(即使是默认值150,150),应用程序也会因此错误而崩溃:

'NSInvalidArgumentException', reason: '-[_SwiftValue X]: unrecognized selector sent to instance 0x7ae52720'

图像视图内的图像可以在滚动视图框内放大/缩小或平移,并保存在新的缩放或平移状态。

我的目标是始终将滤镜应用于图像视图框的中心,无论内部图像如何放大/缩小或平移。

对于中心键x y值I尝试了数字,imageView.bounds.width / 2的变体,imageView.bounds.height / 2并且我一直遇到同样的崩溃。

我很感激有关获取我的中心钥匙的任何提示或建议!

编辑:我认为这适用于中心键的x,y值,但它仍然将滤镜中心保持在图像本身的原点(左下角)

let frm: CGRect = imageView.frame

filter?.setValue((CIVector(x:frm.size.width * 0.5 , y:frm.size.height * 0.5)), forKey: kCIInputCenterKey)

EDIT2:这里我的imageView和scrollview如何相互关联,我从IB中的Scroll视图开始,设置了所有约束,然后以编程方式添加了imageView:

imageView.frame = CGRect(x: 0, y: 0, width: scrollView.frame.size.width, height: scrollView.frame.size.height)
    imageView.isUserInteractionEnabled = true
    scrollView.addSubview(imageView)

这是我的图像选择器控制器功能:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    image = info[UIImagePickerControllerOriginalImage] as! UIImage

    scrollView.isHidden = false
    noImageHolder.isHidden = true
    imageView.image = image
    imageView.contentMode = UIViewContentMode.center
    imageView.frame = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)

    scrollView.contentSize = image.size

    let scrollViewFrame = scrollView.frame
    let scaleWidth = scrollViewFrame.size.width / scrollView.contentSize.width
    let scaleHeight = scrollViewFrame.size.height / scrollView.contentSize.height
    let minScale = min(scaleHeight, scaleWidth)

    scrollView.minimumZoomScale = minScale / 2
    scrollView.maximumZoomScale = 5
    scrollView.zoomScale = minScale
}

最后,此函数将imageView的内容集中在scrollview中:

func centerScrollViewContents(){

    let boundsSize = scrollView.bounds.size
    var contentsFrame = imageView.frame

    if contentsFrame.size.width < boundsSize.width{
        contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2
    }else{
        contentsFrame.origin.x = 0
    }

    if contentsFrame.size.height < boundsSize.height{
        contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2
    }else{
        contentsFrame.origin.y = 0
    }

    imageView.frame = contentsFrame

}

1 个答案:

答案 0 :(得分:2)

根据参考资料,您需要为CIVector传递kCIInputCenterKey

k​CIInput​Center​Key

试试这个:

filter?.setValue(CIVector(x:0, y:0), forKey: kCIInputCenterKey)

正如我在第一条评论中所述,您需要利用UIScrollViewcontentSizecontentOffsetzoomScale的某些属性来转换UIScrollView基于内容坐标的坐标。

通常,您只需添加contentOffset

    let cx = scrollView.frame.width/2 + scrollView.contentOffset.x
    let cy = scrollView.frame.height/2 + scrollView.contentOffset.y

坐标(cx, cy)代表基于内容的坐标系中scrollView的中心。

但是,如果您想要一个适用于CIFilter的坐标,您可能需要将此基于内容的坐标转换为基于图像的坐标。也许简单的缩放可行,但无法确定您的 EDIT2 代码。