按角度和 Core Image 坐标系旋转 CIImage

Rotating CIImage by angle & Core Image coordinate system

我对 Core Image 坐标系、应用变换的方式和确定范围有一些疑问。我在文档或互联网上找不到太多内容,所以我尝试了以下代码来旋转 CIImage 并将其显示在 UIImageView 中。

 override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    
    imageView.contentMode = .scaleAspectFit
    let uiImage = UIImage(contentsOfFile: imagePath)
    
    ciImage = CIImage(cgImage: (uiImage?.cgImage)!)
    imageView.image = uiImage
}

private var currentAngle = CGFloat(0)
private var ciImage:CIImage!
private var ciContext = CIContext()

  @IBAction func rotateImage() {
    
    let extent = ciImage.extent
    
    let translate = CGAffineTransform(translationX: extent.midX, y: extent.midY)
    let uiImage = UIImage(contentsOfFile: imagePath)
    
    currentAngle = currentAngle + CGFloat.pi/10
    
    let rotate = CGAffineTransform(rotationAngle: currentAngle)
    let translateBack = CGAffineTransform(translationX: -extent.midX, y: -extent.midY)
    
    let transform = translateBack.concatenating(rotate.concatenating(translate))
    
    ciImage = CIImage(cgImage: (uiImage?.cgImage)!)
    ciImage = ciImage.transformed(by: transform)
    
    NSLog("Extent \(ciImage.extent), Angle \(currentAngle)")
    let cgImage = ciContext.createCGImage(ciImage, from: ciImage.extent)
    
    imageView.image = UIImage(cgImage: cgImage!)
}

因此,当我每次按下按钮旋转图像时,图像每次都会旋转 pi/10 角度。但是我看到图像在 UIImageView 中缩小了。 NSLogs 显示范围随着一些旋转而增长,原点 x 和 y 变为负值。

  2021-09-24 14:43:29.280393+0400 CoreImagePrototypes[65817:5175194] Metal API Validation Enabled
  2021-09-24 14:43:31.094877+0400 CoreImagePrototypes[65817:5175194] Extent (-105.0, -105.0, 1010.0, 1010.0), Angle 0.3141592653589793
  2021-09-24 14:43:41.426371+0400 CoreImagePrototypes[65817:5175194] Extent (-159.0, -159.0, 1118.0, 1118.0), Angle 0.6283185307179586
  2021-09-24 14:43:42.244703+0400 CoreImagePrototypes[65817:5175194] Extent (-159.0, -159.0, 1118.0, 1118.0), Angle 0.9424777960769379
  2021-09-24 14:43:42.644446+0400 CoreImagePrototypes[65817:5175194] Extent (-105.0, -105.0, 1010.0, 1010.0), Angle 1.2566370614359172
  2021-09-24 14:43:43.037312+0400 CoreImagePrototypes[65817:5175194] Extent (0.0, 0.0, 800.0, 800.0), Angle 1.5707963267948966
  2021-09-24 14:43:43.478774+0400 CoreImagePrototypes[65817:5175194] Extent (-105.0, -105.0, 1010.0, 1010.0), Angle 1.8849555921538759
  2021-09-24 14:43:44.045811+0400 CoreImagePrototypes[65817:5175194] Extent (-159.0, -159.0, 1118.0, 1118.0), Angle 2.199114857512855

我的问题:

  1. 如何确定比例因子以重新缩放图像,使范围不与原始图像矩形相交?

  2. 负范围原点到底是什么意思?相对于什么是负数?我理解 Core Image 中的坐标系是相对的,假设图像的左下角为 (0,0),而不是像 UIKit 中的某些超级视图。

不清楚问题是什么,但您似乎关注的是 extent 的含义。这就像框架,而且,就像框架一样,如果您对 CIImage 应用了转换,它就失去了意义。旋转后,extent 现在基于变换图像的 边界框 。因此,如果您有一个水平方向较宽的图像并逆时针旋转一点,extent 会变高并且它的顶部会变成负值。