简体   繁体   English

kCIInputCenterKey对于应用于我的imageView内的图像的滤镜崩溃,该图像位于scrollView内

[英]kCIInputCenterKey crashes for filters applied to an image inside my imageView which is inside a scrollView

Here is the function I'm trying to use to apply the CIBumpDistortion to an image loaded in my image view: 这是我要用于将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)!)
    }


}

As of now the above sort of works with the CenterKey commented out. 到目前为止,以上带有CenterKey的作品已被注释掉。 It defaults and applies the filter to the lower left corner of the image. 它默认设置并将滤镜应用于图像的左下角。 If I uncomment it and try to put any values in there (even the default 150, 150) the app crashes with this error: 如果我取消注释并尝试在其中放置任何值(甚至是默认值150、150),应用程序将因以下错误而崩溃:

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

the image inside the image view can be zoomed in/out or panned around inside the scroll view frame and saved in its new zoomed or panned state. 图像视图内的图像可以在滚动视图框架内放大/缩小或平移,并保存为新的缩放或平移状态。

My goal is to have the filter always be applied in the center of the image view frame, regardless of how the image inside is zoomed in/out or panned. 我的目标是始终将滤镜应用于图像视图框架的中心,而不管内部图像如何放大/缩小或平移。

for the center keys xy values I've tried numbers, variations of imageView.bounds.width / 2, imageView.bounds.height / 2 and I keep getting the same crash. 对于中心键xy值,我尝试过数字,imageView.bounds.width / 2的变体,imageView.bounds.height / 2和我一直遇到相同的崩溃。

I would appreciate any tips or advice on getting my my center key figured out! 我会很想得到我的中心钥匙的任何提示或建议!

EDIT: I would think this would work for the x, y values of the center key but it still keeps the filter center at the origin of the image itself (lower left corner) 编辑:我认为这将适用于中心键的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: Here's how my imageView and scrollview relate with each other, I started with the Scroll view in IB, set all of its constraints, then added the imageView programmatically like so: 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)

this is my image picker controller function: 这是我的图像选择器控制器功能:

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
}

And finally this function centers the contents of imageView inside the scrollview: 最后,此函数将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

}

According to the reference, you need to pass CIVector for kCIInputCenterKey . 根据参考,您需要将CIVector传递给kCIInputCenterKey

k​CIInput​Center​Key kCI输入中心键

Try this: 尝试这个:

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

As I have noted in the first comment, you need to utilize some properties of UIScrollView , contentSize , contentOffset or zoomScale , to convert UIScrollView -based coordinates to content-based coordinates. 正如我在第一条评论中指出的那样,您需要利用UIScrollViewcontentSizecontentOffsetzoomScale某些属性将基于UIScrollView的坐标转换为基于内容的坐标。

Generally, you just need to add contentOffset : 通常,您只需要添加contentOffset

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

The coordinate (cx, cy) represents the center of the scrollView in the content-based coordinate system. 坐标(cx, cy)表示基于内容的坐标系中scrollView的中心。

But, if you want a coordinate which works with CIFilter , you may need to convert this content-based coordinate to an image-based coordinate. 但是,如果要使用与CIFilter配合使用的CIFilter ,则可能需要将此基于内容的坐标转换为基于图像的坐标。 Maybe simple scaling would work, but cannot be sure with your EDIT2 code. 也许可以简单地进行缩放,但是不能确定您的EDIT2代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM