Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/104.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios createCGImage(xAE:from:)未使用正确的rect_Ios_Swift_Uiimage_Core Image - Fatal编程技术网

Ios createCGImage(xAE:from:)未使用正确的rect

Ios createCGImage(xAE:from:)未使用正确的rect,ios,swift,uiimage,core-image,Ios,Swift,Uiimage,Core Image,我试图模糊图像的一部分: extension UIImage { func blur(rect: CGRect, radius: CGFloat) -> UIImage? { let context = CIContext(options: nil) let inputImage = CIImage(cgImage: self.cgImage!) let filter = CIFilter(name: "CIGaussianBlur"

我试图模糊图像的一部分:

extension UIImage {
    func blur(rect: CGRect, radius: CGFloat) -> UIImage? {
        let context = CIContext(options: nil)
        let inputImage = CIImage(cgImage: self.cgImage!)
        let filter = CIFilter(name: "CIGaussianBlur")
        filter?.setValue(inputImage, forKey: kCIInputImageKey)
        filter?.setValue(radius, forKey: kCIInputRadiusKey)
        let outputImage = filter?.outputImage
        if let outputImage = outputImage {
            let cgImage = context.createCGImage(outputImage, from: rect)
            if let cgImage = cgImage {
                return UIImage(cgImage: cgImage)
            }
        }
        return nil
    }
}
用法:

guard let blurredImage = self.imageView.image?.blur(rect: self.blur.frame, radius: 2.0) else { fatalError("could not blur image") }
let img = UIImageView(image: blurredImage)
img.frame = self.blur.frame
self.view.addSubview(img)
然而,当应用程序启动时,图片的错误部分会模糊。下面是图片;底部的矩形应该模糊其后面的图像,但它会模糊其他部分


问题是在
viewDidLoad
中添加任何覆盖都不会给出正确的帧大小在侧边添加
viewDidAppear
问题是在
viewDidLoad
中添加任何覆盖都不会给出正确的帧大小在侧边添加
viewDidAppear
您注意到您的插入图像了吗看起来不只是模糊,而是放大了?这应该是一个提示

UIKit视图、帧和图像大小以“点”为单位,这是一种用于布局的显示分辨率无关的单位。您的iPhoneX显示器的点宽度与iPhone6/7/8显示器的点宽度相同,尽管iPhoneX的像素更多。(也就是说,它们的比例系数不同:iPhone6/7/8是2倍的比例,iPhoneX是3倍的比例。)

CGImage
CIImage
测量像素,而不是点,因此在使用UIKit中的视图尺寸时,需要考虑屏幕的比例因子。由于您正在创建要从整个视图模糊的图像,然后仅渲染模糊图像的一部分,因此处理比例因子的位置将在
createCGImage(u:from:)
call中-只需将矩形的原点和大小乘以整个视图的角度即可


另外,请注意,从
UIImage
CIImage
再返回,不一定需要通过
CGImage
,您可以将外部图像视图的图像传递到,并将过滤器的结果传递到。在这种情况下,UIKit和CoreImage为您管理渲染上下文,并可能确保更好的性能(例如,通过将整个管道保持在GPU上)。但是,由于使用render调用来指定裁剪矩形,因此需要在其他地方执行此操作—例如,
CIImage
调用。

您是否注意到插入图像看起来不仅模糊,而且放大了?这应该是一个提示

UIKit视图、帧和图像大小以“点”为单位,这是一种用于布局的显示分辨率无关的单位。您的iPhoneX显示器的点宽度与iPhone6/7/8显示器的点宽度相同,尽管iPhoneX的像素更多。(也就是说,它们的比例系数不同:iPhone6/7/8是2倍的比例,iPhoneX是3倍的比例。)

CGImage
CIImage
测量像素,而不是点,因此在使用UIKit中的视图尺寸时,需要考虑屏幕的比例因子。由于您正在创建要从整个视图模糊的图像,然后仅渲染模糊图像的一部分,因此处理比例因子的位置将在
createCGImage(u:from:)
call中-只需将矩形的原点和大小乘以整个视图的角度即可


另外,请注意,从
UIImage
CIImage
再返回,不一定需要通过
CGImage
,您可以将外部图像视图的图像传递到,并将过滤器的结果传递到。在这种情况下,UIKit和CoreImage为您管理渲染上下文,并可能确保更好的性能(例如,通过将整个管道保持在GPU上)。但是,由于使用render调用来指定裁剪矩形,因此需要在其他地方执行此操作—例如,
CIImage
调用。

看起来您的操作是正确的。有几件事需要解决

可以通过将屏幕比例传递到方法并更新rect的原点和大小来调整比例

由于CoreGraphics和UIKit坐标系之间的转换,模糊部分的定位被关闭。为了解决这个问题,您只需要将窗口的高度减去要模糊的矩形的位置和高度(考虑比例)

请查看以下代码:

extension UIImage {
    func blur(rect: CGRect, radius: CGFloat, scale: CGFloat) -> UIImage? {

        if let cgImage = self.cgImage {
            let inputImage = CIImage(cgImage: cgImage)
            let context = CIContext(options: nil)
            let filter = CIFilter(name: "CIGaussianBlur")
            filter?.setValue(inputImage, forKey: kCIInputImageKey)
            filter?.setValue(radius, forKey: kCIInputRadiusKey)

            // Rect bounds need to be adjusted for based on Image's Scale and Container's Scale
            // Y Position Needs to be Inverted because of UIKit <-> CoreGraphics Coordinate Systems

            let newRect = CGRect(
                x: rect.minX * scale,
                y: ((((CGFloat(cgImage.height) / scale)) - rect.minY - rect.height) * scale),
                width: rect.width * scale,
                height: rect.height * scale
            )


            if let outputImage = filter?.outputImage,
                let cgImage = context.createCGImage(outputImage, from: newRect) {
                return UIImage(
                    cgImage: cgImage,
                    scale: scale,
                    orientation: imageOrientation
                )
            }
        }
        return nil
    }
}

let blurredImage = self.imageView.image?.blur(rect: self.blur.frame, radius: 2.0, scale: UIScreen.main.scale)
扩展UIImage{ func模糊(rect:CGRect,半径:CGFloat,比例:CGFloat)->UIImage{ 如果让cgImage=self.cgImage{ 让inputImage=CIImage(cgImage:cgImage) let context=CIContext(选项:nil) let filter=CIFilter(名称:“CIGaussianBlur”) 过滤器?.setValue(输入图像,forKey:kCIInputImageKey) 过滤器?.setValue(半径,分叉:kCIInputRadiusKey) //矩形边界需要根据图像的比例和容器的比例进行调整 //由于UIKit CoreGraphics坐标系,Y位置需要反转 设newRect=CGRect( x:rect.minX*比例, y:(((CGFloat(cgImage.height)/比例)-rect.minY-rect.height)*比例), 宽度:矩形宽度*比例, 高度:矩形高度*比例 ) 如果let outputImage=filter?.outputImage, 让cgImage=context.createCGImage(outputImage,from:newRect){ 返回UIImage( cgImage:cgImage, 比例:比例, 方向:图像方向 ) } } 归零 } } 让blurredImage=self.imageView.image?.blur(rect:self.blur.frame,半径:2.0,比例:UIScreen.main.scale)
看来你走对了方向。有几件事需要解决

可以通过将屏幕比例传递到方法并更新rect的原点和大小来调整比例

由于CoreGraphics和UIKit坐标系之间的转换,模糊部分的定位被关闭。为了解决这个问题,您只需要将窗口的高度减去要模糊的矩形的位置和高度(考虑比例)

请查看以下代码:

extension UIImage {
    func blur(rect: CGRect, radius: CGFloat, scale: CGFloat) -> UIImage? {

        if let cgImage = self.cgImage {
            let inputImage = CIImage(cgImage: cgImage)
            let context = CIContext(options: nil)
            let filter = CIFilter(name: "CIGaussianBlur")
            filter?.setValue(inputImage, forKey: kCIInputImageKey)
            filter?.setValue(radius, forKey: kCIInputRadiusKey)

            // Rect bounds need to be adjusted for based on Image's Scale and Container's Scale
            // Y Position Needs to be Inverted because of UIKit <-> CoreGraphics Coordinate Systems

            let newRect = CGRect(
                x: rect.minX * scale,
                y: ((((CGFloat(cgImage.height) / scale)) - rect.minY - rect.height) * scale),
                width: rect.width * scale,
                height: rect.height * scale
            )


            if let outputImage = filter?.outputImage,
                let cgImage = context.createCGImage(outputImage, from: newRect) {
                return UIImage(
                    cgImage: cgImage,
                    scale: scale,
                    orientation: imageOrientation
                )
            }
        }
        return nil
    }
}

let blurredImage = self.imageView.image?.blur(rect: self.blur.frame, radius: 2.0, scale: UIScreen.main.scale)
扩展UIImage{ func模糊(矩形:CGRect,半径:CGFloat,sca