2017-03-28 37 views
1

我正在使用CIImage,虽然我知道它不是线性图像,但它确实保存了一些数据。以像素或点为单位的CIImage范围?

我的问题是CIImage的extent属性是否返回像素或点?根据documentation,它说很少,它是工作空间坐标。这是否意味着无法从CIImage获取像素/点,我必须转换为UIImage才能使用.size属性获取点?

我有一个UIImage具有一定的大小,并且当我使用UIImage创建CIImage时,范围显示为点。但是,如果我通过CIFilter来扩展CIImage,我有时会得到像素值返回的范围。

回答

1

我会尽我所能回答。

如果您的消息来源是UIImage,它的size将与范围相同。但请注意,这不是一个UIImageView(大小以点为单位)。我们只是在谈论来源图片。

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

但是,取决于CIFilter,您可能会正在更改大小/范围。某些过滤器会创建一个蒙版或图块。这些实际上可能具有无限大的范围!其他(模糊是一个很好的例子)对周围像素进行采样,因此它们的范围实际上会增加,因为它们会在源图像大小之外对“像素”进行采样(定制这些是CIWarpKernel。)

是的,相当多。以此为底线:

  • 过滤器在干什么?它是否需要简单地检查一个像素的RGB并做一些事情?然后,UIImage大小应该是输出CIImage范围。
  • 滤镜是否产生依赖于像素周围像素的东西?然后输出CIImage范围稍大。多少可能取决于过滤器。
  • 有些过滤器产生的东西与输入无关。其中大多数可能没有真正的程度,因为它们可以是无限的。

点是UIKit和CoreGraphics总是使用的。像素? CoreImage在某些时候可以做到,但是它的低级别(除非你想编写自己的内核),你不应该在意。范围通常可以 - 但请记住上述 - 等于UIImage大小。

编辑

很多图片(尤其是生的)能有这么大的尺寸,以影响性能。我有一个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。我在渲染它之前以及在创建用于CIFilter的CIImage之前对图像执行此操作。

+0

这是否意味着在绘制到像GLKView或MTKView之类的东西时,程度无法用于精确预测像素大小?我使用的targetSizes是image.extent,但由于它们如此多变,它并不总是正确的。到目前为止,使用inputScaleFactor从CIFilter发出的任何内容都将显示像素,但UIImage仅显示点。 – kineticac

+0

当我使用GLKView时,它是一个与此类似的子类:https://github.com/objcio/issue-21-core-image-explorer/blob/master/Core%20Image%20Explorer/FilteredImageView.swift。我非常喜欢CIImage,就像我做UIImage一样。也就是说,我布置一个GLKView,就像我将一个UIImageView一样,在draw(rect :)中设置AspectFit,给GLKView一个图像,并调用setNeedsDisplay()来触发事物。除了使用自动布局的布局外,我并不关心像素/点。希望有所帮助。 – dfd

+0

感谢您的回应!我正在处理来自不同来源的照片,其中一个是来自imageRequest的UIImage,另一个是使用CIRAWFilterImpl加载RAW。为了简单起见,他们使用相同的代码来渲染视图。问题是,image.extent取决于它来自哪里,这是我现在的问题。解决方案将追踪它们来自哪里,以提供正确的目标大小。 – kineticac

1

我建议你把它们看作点。没有缩放和没有屏幕(CIImage不是绘制的东西),所以没有像素。

一个由CGImage支持的UIImage是绘制的基础,除了CGImage它还有一个尺度;再加上屏幕分辨率,使我们可以从点到像素进行转换。

相关问题