一点背景知识: 我正在将图像附加到现有的pdf文件中。我发现没有办法只添加一个页面,你必须重新创建整个pdf,然后删除旧的,然后移动新的。 (如果这是错误的请告诉我,这将为我节省很多麻烦。)我已经完成了那部分,但我现在正在尝试复制辅助信息(标题,作者) ,钥匙等)。问题是有很多类型问题,我正在使用的当前方法是获取CGPDFDocumentRef的CGPDFDictionaryRef,然后调用CGPDFDictionaryApplierFunction。在我传递的C函数中,我将每个键提取到NSMutableDictionary,这样我就可以对这些值执行某些操作,而不是将它们锁定在这种可怕的CGPDF格式中。
基本上我的问题是: 有没有更好的方法呢?我盯着那么多文档文件,我无法想象遗漏任何东西,但我真的希望我有,因为我不得不做的工作量变得荒谬。
答案 0 :(得分:10)
我已经完成了我的解决方法。我仍然想知道是否有更好的方法来做到这一点,所以如果你知道一个或有任何建议我愿意尝试。
注意:我只检查bool,整数,字符串和数组,因为根据Apple的文档,所有这些都应该在PDF中的辅助信息中。数组位未经测试,因为我在Aux Info中没有带有数组的PDF。如果有人想为我测试一下或者链接到带有一个的pdf,我很乐意测试它。
首先,在类标题中,在id selfClass
标记之外创建@interface
,以便CGPDFDictionaryApplyFunction
调用的C函数可以访问当前类。还要添加NSDictionary *auxInfo
来存储信息。一旦提取,NS类型可以很容易地像这样:
CFDictionaryRef newDictionary = (CFDictionaryRef)[self auxInfo];
我昨晚实际上已经完成但是我认为我必须再做一轮循环才能从NS转换为CF,忘记它们是无令牌桥接的。所以你有它,希望每个人都能从我的工作中受益。如果您需要澄清,请提出问题。再一次,如果有更简单的方法,如果只是优化我的代码,请说出来。我知道这不是一种非常优雅的方法,但它现在有效。
- (void)extractPDFDictionary:(CGPDFDocumentRef)pdf{
NSLog(@"extractingPDFDictionary");
CGPDFDictionaryRef oldDict = CGPDFDocumentGetInfo(pdf);
CGPDFDictionaryApplyFunction(oldDict, copyDictionaryValues, NULL);
}
void copyDictionaryValues (const char *key, CGPDFObjectRef object, void *info) {
NSLog(@"key: %s", key);
CGPDFObjectType type = CGPDFObjectGetType(object);
switch (type) {
case kCGPDFObjectTypeString: {
CGPDFStringRef objectString;
if (CGPDFObjectGetValue(object, kCGPDFObjectTypeString, &objectString)) {
NSString *tempStr = (NSString *)CGPDFStringCopyTextString(objectString);
[[selfClass auxInfo] setObject:tempStr
forKey:[NSString stringWithCString:key encoding:NSUTF8StringEncoding]];
[tempStr release];
NSLog(@"set string value");
}
}
case kCGPDFObjectTypeInteger: {
CGPDFInteger objectInteger;
if (CGPDFObjectGetValue(object, kCGPDFObjectTypeInteger, &objectInteger)) {
[[selfClass auxInfo] setObject:[NSNumber numberWithInt:objectInteger]
forKey:[NSString stringWithCString:key encoding:NSUTF8StringEncoding]];
NSLog(@"set int value");
}
}
case kCGPDFObjectTypeBoolean: {
CGPDFBoolean objectBool;
if (CGPDFObjectGetValue(object, kCGPDFObjectTypeBoolean, &objectBool)) {
[[selfClass auxInfo] setObject:[NSNumber numberWithBool:objectBool]
forKey:[NSString stringWithCString:key encoding:NSUTF8StringEncoding]];
NSLog(@"set boolean value");
}
}
case kCGPDFObjectTypeArray : {
CGPDFArrayRef objectArray;
if (CGPDFObjectGetValue(object, kCGPDFObjectTypeArray, &objectArray)) {
NSArray *tempArr = [selfClass copyPDFArray:objectArray];
[[selfClass auxInfo] setObject:tempArr
forKey:[NSString stringWithCString:key encoding:NSUTF8StringEncoding]];
[tempArr release];
NSLog(@"set array value");
}
}
}
}
- (NSArray *)copyPDFArray:(CGPDFArrayRef)arr{
int i = 0;
NSMutableArray *temp = [[NSMutableArray alloc] init];
for(i=0; i<CGPDFArrayGetCount(arr); i++){
CGPDFObjectRef object;
CGPDFArrayGetObject(arr, i, &object);
CGPDFObjectType type = CGPDFObjectGetType(object);
switch(type){
case kCGPDFObjectTypeString: {
CGPDFStringRef objectString;
if (CGPDFObjectGetValue(object, kCGPDFObjectTypeString, &objectString)) {
NSString *tempStr = (NSString *)CGPDFStringCopyTextString(objectString);
[temp addObject:tempStr];
[tempStr release];
}
}
case kCGPDFObjectTypeInteger: {
CGPDFInteger objectInteger;
if (CGPDFObjectGetValue(object, kCGPDFObjectTypeInteger, &objectInteger)) {
[temp addObject:[NSNumber numberWithInt:objectInteger]];
}
}
case kCGPDFObjectTypeBoolean: {
CGPDFBoolean objectBool;
if (CGPDFObjectGetValue(object, kCGPDFObjectTypeBoolean, &objectBool)) {
[temp addObject:[NSNumber numberWithBool:objectBool]];
}
}
case kCGPDFObjectTypeArray : {
CGPDFArrayRef objectArray;
if (CGPDFObjectGetValue(object, kCGPDFObjectTypeArray, &objectArray)) {
NSArray *tempArr = [selfClass copyPDFArray:objectArray];
[temp addObject:tempArr];
[tempArr release];
}
}
}
}
return temp;
}
答案 1 :(得分:0)
您可以通过绘制CGPDFContext
来完成您所描述的内容,但如果您有复杂的PDF,则可能会尝试超出API的目的。您可以查看PDF spec的第3.4节,看看您要了解的内容。