2010-08-10 105 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