CIImage的extent是以像素还是点为单位?

4
我正在使用CIImage,虽然我知道它不是线性图像,但它确实包含一些数据。
我的问题是CIImage的extent属性返回像素还是点?根据文档,它是工作空间坐标。这是否意味着无法从CIImage获取像素/点,必须将其转换为UIImage以使用.size属性获取点?
我有一个特定大小的UIImage,当我使用UIImage创建CIImage时,extent以点的形式显示。但是,如果我通过CIFilter运行CIImage进行缩放,则有时会返回以像素值表示的extent。
2个回答

6

我会尽力给出最好的答案。

如果您的源是UIImage,则其大小将与范围相同。但请注意,这不是UIImageView(其中大小以点为单位)。我们只谈论图像。

通过CIFilter运行一些东西意味着您正在操作它们。如果你所做的只是操作颜色,则其大小/范围不应改变(与创建自己的CIColorKernel相同 - 它逐像素工作)。

但是,根据CIFilter,您可能会更改大小/范围。某些滤镜创建掩码或平铺。这些实际上可能具有无限的范围!其他过滤器(模糊是一个很好的例子)对周围的像素进行采样,因此它们的范围实际上会增加,因为它们采样超出源图像大小的“像素”。 (自定义方式这些是CIWarpKernel。)

是的,相当多。归纳如下:

  • 滤镜在做什么?是否需要仅检查像素的RGB并执行某些操作?然后UIImage大小应为输出CIImage范围。
  • 滤镜是否产生取决于像素周围像素的内容?然后,输出CIImage范围略微扩大。多少可能取决于滤镜。
  • 有些滤镜可以产生与输入无关的东西。这些中的大多数可能没有真正的范围,因为它们可以是无限的。

点是UIKit和CoreGraphics始终使用的单位。像素?在某些时候CoreImage确实会用到,但在某种程度上(除非您想编写自己的内核)低级别,您不必关心。通常可以将范围与UIImage大小相等。

编辑

许多图像(特别是RAW图像)可能具有如此大的大小,以至于会影响性能。我有一个UIImage的扩展,将图像调整大小到特定矩形,以帮助保持一致的CI性能。

extension UIImage {
    public func resizeToBoundingSquare(_ boundingSquareSideLength : CGFloat) -> UIImage {
        let imgScale = self.size.width > self.size.height ? boundingSquareSideLength / self.size.width : boundingSquareSideLength / self.size.height
        let newWidth = self.size.width * imgScale
        let newHeight = self.size.height * imgScale
        let newSize = CGSize(width: newWidth, height: newHeight)
        UIGraphicsBeginImageContext(newSize)
        self.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
        let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext();
        return resizedImage!
    }
}

使用方法:

image = image.resizeToBoundingSquare(640)

在这个例子中,一个大小为3200x2000的图片会被缩小到640x400。或者一个大小为320x200的图片会被放大到640x400。在渲染图像和创建CIImage以用于CIFilter之前,我会对图像进行此操作。请留下HTML标签,不需要解释。

这是否意味着extent不能用于准确预测像GLKView或MTKView这样的绘图时的像素大小?我正在使用的targetSizes是image.extent,但由于它们如此多样化,它并不总是正确的。到目前为止,任何带有inputScaleFactor的CIFilter输出都将显示像素,但UIImage仅会显示点。 - Art C
当我使用GLKView时,它是一个非常类似于这个子类:https://github.com/objcio/issue-21-core-image-explorer/blob/master/Core%20Image%20Explorer/FilteredImageView.swift。我基本上像对待UIImage一样对待CIImage。也就是说,我像布置UIImageView一样布置GLKView,在draw(rect :)中设置为AspectFit,给GLKView一个图像,并调用setNeedsDisplay()触发事情。我真的不关心像素/点,除了布局之外,我使用自动布局。希望能帮到你。 - user7014451
谢谢回复!我正在处理来自不同来源的照片,其中一个是从imageRequest中获取的UIImage,另一个是使用CIRAWFilterImpl加载的RAW。为了简化事情,它们使用相同的代码呈现到视图中。问题是,image.extent取决于它来自哪里,这就是我的问题所在。解决方案将是跟踪它们的来源以给出正确的目标大小。 - Art C
我会在我的回答中添加一些内容。它可能没有什么帮助,但你永远不知道。 - user7014451

3

建议您将它们视为点。没有刻度和屏幕(CIImage不是绘制的内容),因此没有像素。

以CGImage为基础生成的UIImage用于绘制,除了包含CGImage之外,还有一个比例尺;加上屏幕分辨率,这就是我们从点到像素的转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接