[英]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
。
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. 正如我在第一条评论中指出的那样,您需要利用
UIScrollView
, contentSize
, contentOffset
或zoomScale
某些属性将基于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.