是否可以从CGPDFDocumentRef中检索文档的名称
发布于 2011-05-06 22:08:51
你说的“文档名称”是指文档的文件名还是标题?
如果文档"title“包含在元数据中,则可以像这样检索它:
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
发布于 2020-09-28 07:06:23
以下是如何在Swift 5中做到这一点:
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字典可以包含包括文档标题的元数据。*
guard let infoDict = self.info else {
return nil
}如果是这样,我们会尝试使用CGPDFDictionary应用程序接口从该字典中获取标题。这个API只接受C类型,所以我们需要执行一些转换来将Swift字符串”Title”表示为C字符串。
let titleKey = ("Title" as NSString).cString(using: String.Encoding.ascii.rawValue)!CGPDFDictionaryGetString调用将指向CGPDFStringRef?变量的指针作为其第三个参数。为了将Swift引用转换为指针,我们在其前面加上&。如果在创建PDF时未指定标题,则字典查找的结果可能为空。
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>>。
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。
if let title = CFStringCreateWithBytes(allocator, optionalTitle, length, encoding, true) {
return title as String
}
}
return nil*本字典中的值的关键字可在Adobe PDF Reference book表10.2“文档信息字典中的条目”中找到,第844页。
https://stackoverflow.com/questions/5881921
复制相似问题