Forum Archive

Need help for CFURLRef in Objectivec

cvp

I want to render a pdf page into an ui.Image without passing via a (WK)WebView because the draw_snapshot of a webview only works if it is presented.

Thus, I want to use this kind of objectivec code:


'''
func drawPDFfromURL(url: URL) -> UIImage? {
    guard let document = CGPDFDocument(url as CFURL) else { return nil }
    guard let page = document.page(at: 1) else { return nil }

    let pageRect = page.getBoxRect(.mediaBox)
    let renderer = UIGraphicsImageRenderer(size: pageRect.size)
    let img = renderer.image { ctx in
        UIColor.white.set()
        ctx.fill(pageRect)

        ctx.cgContext.translateBy(x: 0.0, y: pageRect.size.height)
        ctx.cgContext.scaleBy(x: 1.0, y: -1.0)

        ctx.cgContext.drawPDFPage(page)
    }

    return img
}

But I already meet a problem with the first line 😢 with the CFURLRef.
Can a guru help me to convert a string url ("file://.....") into this CFURLRef.
I think and hope that next lines would be easier to convert.
Thanks a lot

dgelessus

From an Objective-C perspective, CFURLRef is basically identical to NSURL *, because of "toll-free bridging" between Core Foundation and Objective-C/Foundation. (This also applies to other CF types, like CFStringRef/NSString *, CFArrayRef/NSArray *, etc.) So you should be able to create a NSURL from a string normally (using objc_util.nsurl) and pass the ObjCInstance into the parameter that expects a CFURLRef.

cvp

@dgelessus Thanks a lot, I'll try

cvp

It seems that the code that I wanted to convert is perhaps obsolete because document.page does not work, but I've found other functions....
Until here, this is ok (but not yet very far)
```
url = '3 instincts.pdf'
url = os.path.join(os.getcwd(), url)
ns_url = nsurl(url)

document = CGPDFDocumentCreateWithURL(ObjCInstance(ns_url))
print(dir(ObjCInstance(document)))

np = CGPDFDocumentGetNumberOfPages(document)
print('CGPDFDocumentGetNumberOfPages=',np)

page = CGPDFDocumentGetPage(document,10)

page_number = CGPDFPageGetPageNumber(page)
print('CGPDFPageGetPageNumber=',page_number)

page_mediabox = CGPDFPageGetBoxRect(page,0) # CGPDFBox = 0 => kCGPDFMediaBox ```

cvp

Segmentation fault in CGContextDrawPDFPage(c,page)


from  objc_util import *
import os
import ui

# https://flylib.com/books/en/3.310.1.73/1/

UIGraphicsGetCurrentContext = c.UIGraphicsGetCurrentContext
CGPDFDocumentCreateWithURL = c.CGPDFDocumentCreateWithURL
CGPDFDocumentCreateWithURL.restype = c_void_p
CGPDFDocumentCreateWithURL.argtypes = [c_void_p]

CGPDFDocumentGetNumberOfPages = c.CGPDFDocumentGetNumberOfPages
CGPDFDocumentGetNumberOfPages.restype = c_void_p
CGPDFDocumentGetNumberOfPages.argtypes = [c_void_p]

CGPDFDocumentGetPage = c.CGPDFDocumentGetPage
CGPDFDocumentGetPage.restype = c_void_p
CGPDFDocumentGetPage.argtypes = [c_void_p, c_void_p]

CGPDFPageGetPageNumber = c.CGPDFPageGetPageNumber
CGPDFPageGetPageNumber.restype = c_void_p
CGPDFPageGetPageNumber.argtypes = [c_void_p]

CGPDFPageGetBoxRect= c.CGPDFPageGetBoxRect
CGPDFPageGetBoxRect.restype = c_void_p
CGPDFPageGetBoxRect.argtypes = [c_void_p,c_void_p]

CGContextDrawPDFPage = c.CGContextDrawPDFPage
CGContextDrawPDFPage.restype = None
CGContextDrawPDFPage.argtypes = [c_void_p,c_void_p]

url = '3 instincts.pdf'
url = os.path.join(os.getcwd(), url)
ns_url = nsurl(url)

document = CGPDFDocumentCreateWithURL(ObjCInstance(ns_url))

np = CGPDFDocumentGetNumberOfPages(document)
print('CGPDFDocumentGetNumberOfPages=',np)  # just to check if document is ok

page = CGPDFDocumentGetPage(document,10)    

page_number = CGPDFPageGetPageNumber(page)
print('CGPDFPageGetPageNumber=',page_number)    # just to check if page is ok

#page_mediabox = CGPDFPageGetBoxRect(page,0)    # CGPDFBox = 0 => kCGPDFMediaBox

with ui.ImageContext(300,300) as context:
    c = UIGraphicsGetCurrentContext()
    CGContextDrawPDFPage(c,page) # <====== segmentation fault
    ui_image = context.get_image()

ui_image.show()
cvp

This is also ok,

.
.
CGPDFPageGetBoxRect.restype = CGRect
.
.
page_mediabox = CGPDFPageGetBoxRect(page,0) # CGPDFBox = 0 => kCGPDFMediaBox
w = page_mediabox.size.width
h = page_mediabox.size.height
print('mediabox=',w,h)          # just to check if mediabox is ok 

but always segmentation fault...

cvp

My fault, I forgot to define restyle and argtypes of UIGraphicsGetCurrentContext

UIGraphicsGetCurrentContext = c.UIGraphicsGetCurrentContext
UIGraphicsGetCurrentContext.restype = c_void_p
UIGraphicsGetCurrentContext.argtypes = [] 
cvp

One more time, thanks to @dgelessus for his quick and useful help

See here