【问题标题】:how to get EmbeddedFiles from FileAttachment Annotation in pdf file如何从 pdf 文件中的 FileAttachment Annotation 获取 EmbeddedFiles
【发布时间】:2013-09-05 06:59:43
【问题描述】:

我正在开发 PDF 注释应用程序我在 iPhone 中添加了 PDF 文件注释它工作正常它的注释也可见任何阅读器但面临一个问题如何从 PDF 文件中的文件附件注释中获取 EmbeddedFiles,其是从桌面创建的注释如何做对于这个问题

我正在使用此代码从文件附件注释中获取注释的内容和位置,它工作正常

 CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(pPage);
      //  NSLog(@"%@",(NSDictionary*)pageDictionary);
        CGPDFArrayRef outputArray;
        if(!CGPDFDictionaryGetArray(pageDictionary, "Annots", &outputArray)) {
            [pdfAnnots release];
            return nil;
        }
     CGPDFArrayRef rectArray;
                if(!CGPDFDictionaryGetArray(annotDict, "Rect", &rectArray)) {
                    break;
                }

                int arrayCount = CGPDFArrayGetCount( rectArray );
                CGPDFReal coords[4];
                for( int k = 0; k < arrayCount; ++k ) {
                    CGPDFObjectRef rectObj;
                    if(!CGPDFArrayGetObject(rectArray, k, &rectObj)) {
                        break;
                    }

                    CGPDFReal coord;
                    if(!CGPDFObjectGetValue(rectObj, kCGPDFObjectTypeReal, &coord)) {
                        break;
                    }

                    coords[k] = coord;
                }               

                CGRect rect = CGRectMake(coords[0],coords[1],coords[2],coords[3]);

                NSLog(@"%@",NSStringFromCGRect(rect));

 CGPDFDictionaryRef aDict;

    if(CGPDFDictionaryGetDictionary(annotDict, "AP", &aDict)) 
    {

      CGPDFStreamRef textStringRef33;
        if(CGPDFDictionaryGetStream(aDict, "N", &textStringRef33)) {



            CGPDFDataFormat *format = NULL;

            CFDataRef contdata = CGPDFStreamCopyData( textStringRef33, format );

            NSData *data=(NSData*)contdata;
   }

请帮帮我

提前谢谢你

【问题讨论】:

    标签: iphone ios objective-c pdf


    【解决方案1】:

    PDF 嵌入与注释不同。嵌入文件存储在document 部分而不是page 部分。

    注解可以包含嵌入文件,但提取的机制不同。

    首先,您应该看到注解对象的内部结构。你可以使用这样的函数:

    static void op_Applier(const char *key, CGPDFObjectRef value, void *info) {
        if (*(int *)info > 6) {
            return;
        }
        const char *valuestr = NULL;
        CGPDFObjectType type = CGPDFObjectGetType(value);
        int i = 0;
        for (i = 0; i < *(int *)info; i++) {
            printf("\t");
        }
        printf("%s", key);
        switch (type) {
            case kCGPDFObjectTypeBoolean: {
                bool b;
                CGPDFObjectGetValue(value, type, &b);
                printf(" (boolean) : %s\n", (b)?"true":"false");
            }
                break;
            case kCGPDFObjectTypeInteger: {
                int64_t i;
                CGPDFObjectGetValue(value, type, &i);
                printf(" (integer) : %lld\n", i);
            }
                break;
            case kCGPDFObjectTypeReal: {
                CGPDFReal f;
                CGPDFObjectGetValue(value, type, &f);
                printf(" (real) : %f\n", f);
            }
                break;
            case kCGPDFObjectTypeName:{
                CGPDFObjectGetValue(value, type, (void *)&valuestr);
                printf(" (name) : %s\n", valuestr);
            }
                break;
            case kCGPDFObjectTypeString: {
                CGPDFStringRef str;
                CGPDFObjectGetValue(value, type, &str);
                printf(" (string) : %s\n", CGPDFStringGetBytePtr(str));
            }
                break;
            case kCGPDFObjectTypeArray: {
                printf(" (array)\n");
                CGPDFArrayRef arr;
                CGPDFObjectGetValue(value, type, &arr);
    
                int t = *(int *)info + 1;
                int j;
                size_t size = CGPDFArrayGetCount(arr);
                for (j = 0; j < size; j ++) {
                    CGPDFObjectRef obj;
                    CGPDFArrayGetObject(arr, j, &obj);
                    char buf[4] = {0};
                    sprintf(buf, "%d", j);
                    op_Applier(buf, obj, &t);
                }
            }
                break;
            case kCGPDFObjectTypeDictionary: {
                printf(" (dictionary)\n");
                CGPDFDictionaryRef dict;
                CGPDFObjectGetValue(value, type, &dict);
                int t = *(int *)info + 1;
                CGPDFDictionaryApplyFunction(dict, &op_Applier, &t);
            }
                break;
            case kCGPDFObjectTypeStream:
                printf(" (stream)\n");
                break;
            default:
                printf(" (NULL)\n");
                break;
        }
    }
    
    int t = 0; op_Applier("MyDictionary", yourAnnotationDictionary, &t);
    

    其次,您应该找到文件的路径(它将是stream 对象),然后移动到该对象。这可以通过CGPDFDictionary 方法完成。

    第三,从流中获取NSData,并保存

    CGPDFDataFormat format;
    CFDataRef data = CGPDFStreamCopyData(stream, &format);
    
    [((__bridge NSData *)data) writeToURL:resultUrl atomically:NO];
    
    CFRelease(data);
    

    附: PDF 注释的 PostScript 语法可以不同。不同的库使用不同的语法,您应该实现所有可能性来制作适用于几乎所有 PDF 文件的应用程序。样品可以在this file in vfr Reader找到

    【讨论】:

      猜你喜欢
      • 2013-09-05
      • 1970-01-01
      • 1970-01-01
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      • 2010-10-01
      • 1970-01-01
      • 2018-03-04
      相关资源
      最近更新 更多