将CIImage调整为精确大小

5

我正在寻找一种方式来调整 CIImage 大小,使其精确地达到所需的大小,因为我正在使用混合 CIFilter,需要两个混合后的 CIImage 的大小相同。我需要使用 CIFilter 来调整图像的大小,因为这对我的内存来说更加实惠,而且我无法使用 Core Graphics 等其他方法。

我知道有一个可用的 CILanczosScaleTransform 滤镜,但它不允许调整为精确的大小,只能缩小或放大比例。

是否有一种方法可以通过仅使用 Core Image 来使 CIImage 变为精确的大小?


你有什么缩放行为的想法?如果纵横比不匹配,应该裁剪还是拉伸? - Frank Rupprecht
它可能会被拉伸。图像的主要优先级是按照请求的确切大小呈现。 - SmartTree
2个回答

17

CILanczosScaleTransform有两个参数:

  • scale: 图像要使用的缩放因子
  • aspectRatio: 图像要使用的附加水平缩放因子

使用这两个参数,您可以实现目标图像大小。计算垂直维度的缩放因子以获得所需的高度,然后计算应用于水平维度的此缩放的结果。这可能与目标宽度不匹配,因此计算纵横比以应用于缩放宽度以将其校正为所需的目标宽度。

import CoreImage

let context = CIContext()
let imageURL = URL(fileURLWithPath: "sample.jpg")
let sourceImage = CIImage(contentsOf: imageURL, options: nil)
let resizeFilter = CIFilter(name:"CILanczosScaleTransform")!

// Desired output size
let targetSize = NSSize(width:190, height:230)

// Compute scale and corrective aspect ratio
let scale = targetSize.height / (sourceImage?.extent.height)!
let aspectRatio = targetSize.width/((sourceImage?.extent.width)! * scale)

// Apply resizing
resizeFilter.setValue(sourceImage, forKey: kCIInputImageKey)
resizeFilter.setValue(scale, forKey: kCIInputScaleKey)
resizeFilter.setValue(aspectRatio, forKey: kCIInputAspectRatioKey)
let outputImage = resizeFilter.outputImage

我的示例图像具有尺寸 (w 2,048 h 1,536)。计算得出的缩放因子为0.1497395833333333,长宽比为0.6195652173913043,因此目标输出尺寸为(w 190 h 230)


1
谢谢!这个完美地解决了问题。计算部分正是我所需要的 :) - SmartTree
我遇到了未解决的标识符NSSize,所以我使用了CGSize,但是调整大小通常会偏差1像素。例如,我可能得到189 x 230而不是始终得到190x230。 - sickerin
@sickerin NSSizeCGSize 的类型别名,所以不应该有任何区别。源图像的尺寸是多少?也许这是一个四舍五入误差。 - gavinb
@gavinb 实际上我也遇到了同样的问题,最终结果偏移了一个像素。我想知道是否有什么办法可以解决?源图像大小总是不同的。 - SmartTree
@SmartTree 源图像和目标图像的尺寸是多少? - gavinb
1
同时使用CIAffineTransform滤镜。 - Alisher

4
如果您只想扩展画布并保留原始图像,请使用此选项。
ciimage.clampedToExtent().cropped(to: CGRect(x: 0, y: 0, width: 100, height: 100))

或者您可能希望缩放整个图像,然后使用此选项:

ciimage.transformed(by: CGAffineTransform(scaleX: 10, y: 10))

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