Rotating a page in a pdf file - and get a mirrored image

I try to rotate a page 180° in a pdf file.

I nearly get it, but the page is also mirrored horizontally. Some images to illustrate:

Initial page:

Result after rotation (see code): it is rotated 180° BUT mirrored horizontally as well:

The expected result

It is just as if it was rotated 180°, around the x axis of the page. And I would need to rotate 180° around z axis (perpendicular to the page). It is probably the result of

    writeContext!.scaleBy(x: 1, y: -1)

I have tried a lot of changes for transform, translate, scale parameters, including removing calls to some of them, to no avail.

@IBAction func createNewPDF(_ sender: UIButton) {
    
    var originalPdfDocument: CGPDFDocument!
    
    let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let documentsDirectory = urls[0]
    
    // read some pdf from bundle for test
    if let path = Bundle.main.path(forResource: "Test", ofType: "pdf"), let pdf = CGPDFDocument(URL(fileURLWithPath: path) as CFURL) {
        originalPdfDocument = pdf
    } else { return }
    
    // create new pdf
    let modifiedPdfURL = documentsDirectory.appendingPathComponent("Modified.pdf")
    
    guard let page = originalPdfDocument.page(at: 1) else { return }  // Starts at page 1

    var mediaBox: CGRect = page.getBoxRect(CGPDFBox.mediaBox)  // mediabox which will set the height and width of page
    let writeContext = CGContext(modifiedPdfURL as CFURL, mediaBox: &mediaBox, nil) // get the context
    
    var pageRect: CGRect = page.getBoxRect(CGPDFBox.mediaBox) // get the page rect
    
    writeContext!.beginPage(mediaBox: &pageRect) 
    
    let m = page.getDrawingTransform(.mediaBox, rect: mediaBox, rotate: 0, preserveAspectRatio: true)   // Because of rotate 0, no effect ; changed rotate to 180, then get an empty page
    writeContext!.translateBy(x: 0, y: pageRect.size.height)
    writeContext!.scaleBy(x: 1, y: -1)
    writeContext!.concatenate(m)
    writeContext!.clip(to: pageRect)
    
    writeContext!.drawPDFPage(page) // draw content in page
    writeContext!.endPage() // end the current page
    
    writeContext!.closePDF()
    
}

Note: This is a follow up of a previous thread, https://developer.apple.com/forums/thread/688436

Accepted Reply

Finally fixed it:

I added a "rotation" along y axis, and now get the correct result:

   // -->> REMOVED THIS.   let m = page.getDrawingTransform(.mediaBox, rect: mediaBox, rotate: 0, preserveAspectRatio: true)  
   writeContext!.translateBy(x: 0, y: pageRect.size.height)
   writeContext!.scaleBy(x: 1, y: -1)
   writeContext!.translateBy(x: pageRect.size.width, y: 0)  // <<<--- ADDED These 2 lines
   writeContext!.scaleBy(x: -1, y: 1)
   // -->> REMOVED THIS.       writeContext!.concatenate(m)

or equivalent :

   writeContext!.translateBy(x: pageRect.size.width y: pageRect.size.height)
   writeContext!.scaleBy(x: -1, y: -1)
  • I should have thought of it earlier: composition of x axis 180° and y axis 180° is z axis 180°, what I was looking for.

Add a Comment

Replies

Finally fixed it:

I added a "rotation" along y axis, and now get the correct result:

   // -->> REMOVED THIS.   let m = page.getDrawingTransform(.mediaBox, rect: mediaBox, rotate: 0, preserveAspectRatio: true)  
   writeContext!.translateBy(x: 0, y: pageRect.size.height)
   writeContext!.scaleBy(x: 1, y: -1)
   writeContext!.translateBy(x: pageRect.size.width, y: 0)  // <<<--- ADDED These 2 lines
   writeContext!.scaleBy(x: -1, y: 1)
   // -->> REMOVED THIS.       writeContext!.concatenate(m)

or equivalent :

   writeContext!.translateBy(x: pageRect.size.width y: pageRect.size.height)
   writeContext!.scaleBy(x: -1, y: -1)
  • I should have thought of it earlier: composition of x axis 180° and y axis 180° is z axis 180°, what I was looking for.

Add a Comment

good catch, helped me

a note: missing a colon:

, y: pageRect.size.height)