核心图像裁剪和缩放图像大小

Core Image crop & scale image to size

我需要从尺寸为 (W,H) 的 ciImage 裁剪尺寸为 (w,h) 的缩略图。缩略图被裁剪并缩放至完全适合大小 (w,h)。使用 Core Image crop & scale transform 生成这个缩略图的正确方法是什么?本质上,我需要使用核心图像实现 scaledAspectFill。

这是我的代码:

    var ciImage = CIImage(cvPixelBuffer: pixelBuffer)
   
    let width = CVPixelBufferGetWidth(pixelBuffer)
    let height = CVPixelBufferGetHeight(pixelBuffer)
    let imageSize = CGSize(width: width, height: height)
    

    var scaledImageRect = CGRect.zero
    
    let widthFactor = size.width / imageSize.width
    let heightFactor = size.height / imageSize.height

    let aspectRatio = max(widthFactor, heightFactor)

    scaledImageRect.size.width = imageSize.width * aspectRatio;
    scaledImageRect.size.height = imageSize.height * aspectRatio;
    scaledImageRect.origin.x = (size.width - scaledImageRect.size.width) / 2.0;
    scaledImageRect.origin.y = (size.height - scaledImageRect.size.height) / 2.0;
    
    ciImage = ciImage.cropped(to: scaledImageRect)

   let rect = CGRect(x: 0, y: 0, width: size.width,
                      height: size.height)

   //Do I need to scale again to fit 'size'??? If so, what should be scaling factor and what's the correct way to apply scaling transform that scales the image from center 
    
    let colorSpace = CGColorSpaceCreateDeviceRGB()

    if let jpegData = context.jpegRepresentation(of: ciImage, colorSpace: colorSpace, options: nil) {
        
      //Write jpegData

    } 

这段代码是否矫枉过正?或者有一种更干净、更好的方法来实现它?

是的,你需要在调用jpegRepresentation之前缩小图像,否则你只会从原始图像中裁剪出一个小矩形。

这段代码对我有用:

let targetSize = CGSize(width: 50, height: 50)
let imageSize = ciImage.extent.size

let widthFactor = targetSize.width / imageSize.width
let heightFactor = targetSize.height / imageSize.height
let scaleFactor = max(widthFactor, heightFactor)

// scale down, retaining the original's aspect ratio
let scaledImage = ciImage.transformed(by: CGAffineTransform(scaleX: scaleFactor, y: scaleFactor))

let xInset = (scaledImage.extent.width - targetSize.width) / 2.0
let yInset = (scaledImage.extent.height - targetSize.height) / 2.0

// crop the center to match the target size
let croppedImage = scaledImage.cropped(to: scaledImage.extent.insetBy(dx: xInset, dy: yInset))