首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取文档的CGPDFDocumentRef名称

获取文档的CGPDFDocumentRef名称
EN

Stack Overflow用户
提问于 2011-05-04 18:23:16
回答 2查看 2.6K关注 0票数 5

是否可以从CGPDFDocumentRef中检索文档的名称

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-05-06 22:08:51

你说的“文档名称”是指文档的文件名还是标题?

如果文档"title“包含在元数据中,则可以像这样检索它:

代码语言:javascript
复制
    char *titleKey = "Title";
    CGPDFStringRef titleStringRef;

    CGPDFDictionaryRef info = CGPDFDocumentGetInfo(myDocumentRef);
    CGPDFDictionaryGetString(info, titleKey, &titleStringRef);
    const unsigned char *titleCstring = CGPDFStringGetBytePtr(titleStringRef);

    printf("title: %s", titleCstring);

其他密钥在PDF1.7规范的第10.2节中列出:Adobe PDF Reference Archives

票数 5
EN

Stack Overflow用户

发布于 2020-09-28 07:06:23

以下是如何在Swift 5中做到这一点:

代码语言:javascript
复制
extension CGPDFDocument {
    var title: String? {
        guard let infoDict = self.info else {
            return nil
        }
        let titleKey = ("Title" as NSString).cString(using: String.Encoding.ascii.rawValue)!
        var titleStringRef: CGPDFStringRef?
        CGPDFDictionaryGetString(infoDict, titleKey, &titleStringRef)
        if let stringRef = titleStringRef,
           let cTitle = CGPDFStringGetBytePtr(stringRef) {
            let length = CGPDFStringGetLength(stringRef)
            let encoding = CFStringBuiltInEncodings.UTF8.rawValue
            let allocator = kCFAllocatorDefault
            let optionalTitle: UnsafePointer<UInt8>! = Optional<UnsafePointer<UInt8>>(cTitle)
            if let title = CFStringCreateWithBytes(allocator, optionalTitle, length, encoding, true) {
                return title as String
            }
        }
        return nil
    }
}

下面是我对它的工作原理的理解:

首先,我们检查PDF文档是否附加了info字典。PDF info字典可以包含包括文档标题的元数据。*

代码语言:javascript
复制
        guard let infoDict = self.info else {
            return nil
        }

如果是这样,我们会尝试使用CGPDFDictionary应用程序接口从该字典中获取标题。这个API只接受C类型,所以我们需要执行一些转换来将Swift字符串”Title”表示为C字符串。

代码语言:javascript
复制
        let titleKey = ("Title" as NSString).cString(using: String.Encoding.ascii.rawValue)!

CGPDFDictionaryGetString调用将指向CGPDFStringRef?变量的指针作为其第三个参数。为了将Swift引用转换为指针,我们在其前面加上&。如果在创建PDF时未指定标题,则字典查找的结果可能为空。

代码语言:javascript
复制
        var titleStringRef: CGPDFStringRef?
        CGPDFDictionaryGetString(infoDict, titleKey, &titleStringRef)
        if let stringRef = titleStringRef,
           let cTitle = CGPDFStringGetBytePtr(stringRef) {

在这一点上,我们知道有一个标题字符串,但它还不是可用的Swift字符串。要从内存中读取C字符串(使用CFStringCreateWithBytes),我们需要知道它从哪里开始(指针),以及在多少字节之后停止读取(长度)。此外,我们指定应该使用UTF-8编码读取字符串,并使用默认的内存布局。我们需要的最后一项是对C字符串的正确类型引用。C字符串的类型是指向char的指针,它在内存中表示为UInt8。所以我们最终得到了Optional<UnsafePointer<UInt8>>

代码语言:javascript
复制
            let length = CGPDFStringGetLength(stringRef)
            let encoding = CFStringBuiltInEncodings.UTF8.rawValue
            let allocator = kCFAllocatorDefault
            let optionalTitle: UnsafePointer<UInt8>! = Optional<UnsafePointer<UInt8>>(cTitle)

收集了这些信息后,现在就可以从C字符串中获取Swift字符串了。值得庆幸的是,CFString是免费桥接到Swift的String的,这意味着我们可以使用CFStringCreateWithBytes调用并简单地将结果转换为String。

代码语言:javascript
复制
            if let title = CFStringCreateWithBytes(allocator, optionalTitle, length, encoding, true) {
                return title as String
            }
        }
        return nil

*本字典中的值的关键字可在Adobe PDF Reference book表10.2“文档信息字典中的条目”中找到,第844页。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5881921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档