CIRadialGradient 减小图像尺寸

CIRadialGradient reduces image size

将 CIRadialGradient 应用到我的图像后,它的宽度减少了大约 20%。

guard let image = bgImage.image, let cgimg = image.cgImage else {
    print("imageView doesn't have an image!")
    return
}
let coreImage = CIImage(cgImage:cgimg)

guard let radialMask = CIFilter(name:"CIRadialGradient") else {
    return
}

guard let maskedVariableBlur = CIFilter(name:"CIMaskedVariableBlur") else {
    print("CIMaskedVariableBlur does not exist")
    return 
}
maskedVariableBlur.setValue(coreImage, forKey: kCIInputImageKey)

maskedVariableBlur.setValue(radialMask.outputImage, forKey: "inputMask")
guard let selectivelyFocusedCIImage = maskedVariableBlur.outputImage else {
    print("Setting maskedVariableBlur failed")
    return
}


bgImage.image = UIImage(ciImage: selectivelyFocusedCIImage)

澄清一下,bgImageUIImageView

为什么会发生这种情况,我该如何解决?

没有径向遮罩:

使用径向遮罩:

不同的是,在我的物理 iPhone 上,较小的图像向左对齐。

查看文档,这是应用于图像的蒙版:

文档:CIRadialGradient

我倾向于通过使用 CIContext 并创建特定大小的 CGImage 而不是简单地使用 UIImage(ciImage:) 来明确说明图像有多大。试试这个,假设你的 inputImage 被称为 coreGraphics:

let ciCtx = CIContext()
let cgiig = ctx.createCGImage(selectivelyFocusedCIImage, from: coreImage.extent)
let uiImage = UIImage(cgImage: cgIMG!)

一些注意事项....

(1) 我从我正在打包的应用程序中提取了这段代码。这是未经测试的代码(包括强制解包),但我正在做的事情的概念是可靠的。

(2) 你并没有解释很多你想做的事情,但是当我看到一个名为 selectivelyFocusedCIImage 的变量时,我担心你可能正在尝试以更具交互性的方式使用 CoreImage比 "just" 创建一个图像的方式。如果您想要 "near real-time" 性能,请以 GLKView(自 iOS 12 起已弃用)或 MTKView 而不是 UIImageView 渲染 CIImage。后者仅使用 CPU 而前两者使用 GPU。

(3) 最后,警告 CIContexts - 它们的制作成本很高!通常,您可以对其进行编码,使您的应用程序中的所有内容都只能共享一个上下文。

不同的大小是由模糊滤镜的内核大小引起的:

模糊滤镜需要对每个像素周围的区域进行采样。由于没有超出图像边界的像素,Core Image 将结果图像的 extend 减少一半的内核大小(模糊半径)以表示对于这些像素没有足够的信息来进行适当的模糊。

但是,您可以告诉 Core Image 将边界像素视为在所有方向上无限延伸,以便模糊滤镜即使在图像的边缘也能获得足够的信息。之后您可以将结果裁剪回原始尺寸。

在您的代码中,只需更改以下两行:

maskedVariableBlur.setValue(coreImage.clampedToExtent(), forKey: kCIInputImageKey)

bgImage.image = UIImage(ciImage: selectivelyFocusedCIImage.cropped(to:coreImage.extend))