What exactly is CIImage extent

I have doubts about Core Image coordinate system, way transforms are applied and way the image extent is determined. I couldn't find much in documentation or on internet so I tried the following code to rotate CIImage and display it in UIImageView. As I understand there is no absolute coordinate system in Core Image. The bottom left corner of an image is supposed to be (0,0). But my experiments show something else.

I created a prototype to rotate a CIImage by pi/10 radians on each button click. Here is the code I wrote.

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!)
}

But in the logs, I see the extent of images have negative origin.x and origin.y. What does it mean? Relative to whom it is negative and where exactly is (0,0) then? What exactly is image extent and how does Core Image coordinate system work?

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

Answered by OOPer in 688950022

The doc of extent says:

This rectangle specifies the extent of the image in working space coordinates.

In other words, it is a rectangular region which the processed image is expected to occupy in the same coordinate as in the original image.

Don't you think it is quite reasonable you get negative values when you applied rotation on the image?

WHat is the size of the image ? Isn't rotation around the center of the image (that would explain x is growing negatively, till you reach π/4.

Size of the image is 800x800, but that's not the point I guess. The main goal is understanding how extent is influenced by transform and how exactly does Core Image Coordinate system work? Why the origin of new image formed by rotation negative and not (0,0)? Because without this understanding, it is impossible to develop anything serious and complex.

Accepted Answer

The doc of extent says:

This rectangle specifies the extent of the image in working space coordinates.

In other words, it is a rectangular region which the processed image is expected to occupy in the same coordinate as in the original image.

Don't you think it is quite reasonable you get negative values when you applied rotation on the image?

OOPer image illustrates precisely what I said: rotation is around the center, hence when rotating, the left edge is more on the left (in fact the whole frame is larger). The size was needed to compute how much frame changed.

What exactly is CIImage extent
 
 
Q