以下是我试图将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
}
答案 0 :(得分:2)
根据参考资料,您需要为CIVector
传递kCIInputCenterKey
。
试试这个:
filter?.setValue(CIVector(x:0, y:0), forKey: kCIInputCenterKey)
正如我在第一条评论中所述,您需要利用UIScrollView
,contentSize
,contentOffset
或zoomScale
的某些属性来转换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 代码。