2

私はしばらくの間、PDF パッケージに含まれる PDF ドキュメントを抽出できるように試みてきましたが、うまくいきませんでした。ドキュメントやサンプル コードはどこにも見つかりませんでしたが、Adobe Reader アプリと PDFExpert アプリがサポートしているので、不可能ではないことはわかっています。彼らが独自のパーサーを持っている可能性はありますが、そうならないことを願っています...

私を正しい方向に向けるヒントは大歓迎です

編集:久しぶりに私はこれに取り組み、ついにそれを理解しました。私を正しい方向に向けてくれたiPDFDevに感謝します!!

各内部 CGPDFDocumentRef を取得する方法のコードは次のとおりです。

NSURL *url = [NSURL fileURLWithPath:filePath isDirectory:NO];
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((__bridge CFURLRef)url);
CGPDFDictionaryRef catalog = CGPDFDocumentGetCatalog(pdf);

CGPDFDictionaryRef names = NULL;
if (CGPDFDictionaryGetDictionary(catalog, "Names", &names)) {
    CGPDFDictionaryRef embFiles = NULL;
    if (CGPDFDictionaryGetDictionary(names, "EmbeddedFiles", &embFiles)) {
        // At this point you know this is a Package/Portfolio

        CGPDFArrayRef nameArray = NULL;
        CGPDFDictionaryGetArray(embFiles, "Names", &nameArray);

        // nameArray contains the inner documents
        // it brings the name and then a dictionary from where you can extract the pdf

        for (int i = 0; i < CGPDFArrayGetCount(nameArray); i+=2) {
            CGPDFStringRef name = NULL;
            CGPDFDictionaryRef dict = NULL;

            if (CGPDFArrayGetString(nameArray, i, &name) &&
                CGPDFArrayGetDictionary(nameArray, i+1, &dict)) {
                NSString *_name = [self convertPDFString:name];

                CGPDFDictionaryRef EF;
                if (CGPDFDictionaryGetDictionary(dict, "EF", &EF)) {
                    CGPDFStreamRef F;
                    if (CGPDFDictionaryGetStream(EF, "F", &F)) {
                        CFDataRef data = CGPDFStreamCopyData(F, NULL);
                        CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);

                        CGPDFDocumentRef _doc = CGPDFDocumentCreateWithProvider(provider);
                        if (_doc) {
                            // save the docRef somewhere (_doc)
                            // save the pdf name somewhere (_name)
                        }

                        CFRelease(data);
                        CGDataProviderRelease(provider);
                    }
                }
            }
        }
    }
}



- (NSString *)convertPDFString:(CGPDFStringRef)string {
    CFStringRef cfString = CGPDFStringCopyTextString(string);
    NSString *result = [[NSString alloc] initWithString:(__bridge NSString *)cfString];
    CFRelease(cfString);
    return result;
}
4

1 に答える 1

1

PDFパッケージでは、PDFポートフォリオを参照していると思います。PDFポートフォリオのファイルは、基本的にいくつかの拡張属性を持つドキュメントの添付ファイルであり、EmbeddedFilesツリーにあります。まず、ドキュメントカタログ辞書から始めます。ドキュメントカタログディクショナリから/Namesディクショナリを取得します。/ Namesディクショナリから、存在する場合(オプション)、/EmbeddedFilesディクショナリを取得します。存在する場合は、埋め込みファイルツリー(PDF仕様の名前ツリー)の先頭を表します。
PDF仕様(ここで入手可能:http : //wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf)では、セクション7.9.6で名前ツリーについて説明しています。そして、ツリーを解析する方法がわかります。
ツリーは、文字列識別子をファイル仕様辞書にマップします(セクション7.11.3)。ファイル仕様ディクショナリから、埋め込まれたファイルストリームである/ EFキーの値を取得します(セクション7.11.4)。このオブジェクトに関連付けられているストリームは、探しているファイルコンテンツです。

于 2012-04-18T11:14:21.963 に答える