2010-08-10 71 views
7

一点点背景: 我将图像附加到已存在的pdf文件。我发现没有办法只是添加一个页面,你必须重新创建整个PDF,然后删除旧的,然后移动新的。 (如果这是错误的告诉我,它会为我节省很多头痛。)我已经完成了这部分,但我现在试图复制辅助信息(标题,作者,键等) 。问题是有很多类型问题,我使用的当前方法是获取CGPDFDocumentRef的CGPDFDictionaryRef,然后调用CGPDFDictionaryApplierFunction。在C函数中,我将它传递给一个NSMutableDictionary,这样我就可以对这些值进行一些操作,而不会将它们锁定在这个可怕的CGPDF格式中。CGPDFDictionary提供一些有用的信息

所以基本上我的问题是: 有没有更好的方式来做到这一点?我盯着这么多的文档文件,我无法想象错过任何东西,但真的希望我有,因为我必须做的解决方法的数量越来越荒唐。

+0

我今天也遇到了这个问题。仍在研究解决方案。将会检查这个,如果我找到任何东西,也会发布。 – 2010-08-10 22:13:23

+1

谢谢。当我完成后,我会发布我的解决方法。我真的很讨厌它,因为它的效率非常低。在SDK中没有内置方法的情况下可能会达到它的效果,但它很丑陋。 – alunsford3 2010-08-10 22:28:16

+0

是啊,它看起来很讨厌。我个人正在尝试将pdf对象添加到pdfarray或pdf字典中,并遇到无法访问添加或创建或编辑或插入类似CGPDF对象的问题的相同问题。它的笑话真的是api有多糟糕。 – 2010-08-10 22:38:26

回答

0

您可以通过绘制到CGPDFContext来完成描述,但是如果您有一个复杂的PDF,您可能会尝试超出API的预期目标。你可以看一下PDF spec的第3.4节,看看你在做什么。

+0

您指的是哪一个PDF规范?补充ISO 32000,补充ISO 32000-1或Doc管理?这些看起来没有任何帮助。至于CGPDFContext,据我所知,这是绘画,这是我使用的。但要复制PDF,我必须使用CGPDFDocumentRef从一个PDF中读取,然后根据Apples Quartz 2D Programming Guide绘制到CGPDFContext。 (http://developer.apple.com/mac/library/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_pdf/dq_pdf.html) – alunsford3 2010-08-11 02:31:16

+0

简单的“spec”就足够了,因为我引用的章节最近没有太大变化,至于重写外部参照,等: http://www.adobe.com/devnet/acrobat/pdfs/pdf_reference_1-7.pdf – jbm 2010-08-11 15:50:06

+0

啊谢谢。我认为这比我想要的要低一点。我会将其提交给我的雇主并留给他们。哈哈。 – alunsford3 2010-08-12 18:27:57

10

我已经完成了我的解决方法。我仍然想知道是否有更好的方法来做到这一点,所以如果你知道一个或有任何建议,我愿意尝试。

注意:我只检查bools,整数,字符串和数组,因为根据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; 
} 
+0

+1:很棒的工作,试着用我的修改(因为我没有真正使用它只是为了解析辅助信息)。我会让你知道,如果阵列位也工作。再次感谢。 – 2010-08-12 14:22:16

+0

没问题。尽管只是对代码进行了小小的更新,但在每个案例结束时,我忘记了“休息”。它仍然和我想的一样,但它使交换机正常运行。我做了一些更多的测试,并且我认为它以某种方式忽略了关键字和主键。我必须仔细研究一下。 – alunsford3 2010-08-12 18:27:04

+0

我遇到了一个问题,因为我扩展代码以包含其他对象,是否没有关于pdf名称类型等于CGPDF的指南,我尝试使用CGPDFStringRef类似于字符串大小写,并且它完全怪异。想法? – 2010-08-12 21:55:47