CGPDFDictionaryRef к чему-то полезному

Определенный фон: я добавляю изображение в уже существующий файл PDF. Я узнал, что нет способа просто добавить страницу к нему, необходимо воссоздать целый PDF, затем удалить старый, затем перемещают новый. (Если это неправильно, скажите мне, и это сохранит меня много головных болей.) я выполнил ту часть, но я теперь пробую к копии Вспомогательной Информации (Заголовок, Автор, Ключи, и т.д.). Проблема существует столько проблем типа, что существующий метод, который я использую, состоит в том, чтобы получить CGPDFDictionaryRef CGPDFDocumentRef, затем назвать CGPDFDictionaryApplierFunction. В функции C я передаю его, я извлекаю каждый ключ к NSMutableDictionary так, чтобы я мог затем сделать что-то со значениями и не иметь их, привязал этот ужасный формат CGPDF.

Таким образом, в основном мой вопрос был бы: существует ли лучший способ сделать это? Я уставился на такое количество файлов документации, я не мог предположить пропускать что-либо, но действительно надеяться, что имею, потому что объем обходного решения, которое я должен сделать, становится абсурдным.

7
задан alunsford3 10 August 2010 в 22:10
поделиться

2 ответа

Вы можете выполнить то, что описываете, нарисовав в CGPDFContext , но если у вас сложный PDF-файл, вы можете предпринять что-то, выходящее за рамки того, для чего был предназначен API. Вы можете взглянуть на раздел 3.4 спецификации PDF и увидеть, во что вы ввязываетесь.

0
ответ дан 6 December 2019 в 22:59
поделиться

Я выполнил обходной путь. Я все еще хотел бы знать, есть ли лучший способ сделать это, поэтому, если вы знаете один или у вас есть какие-либо предложения, я готов их попробовать.

Примечания: Я проверяю только логические значения, целые числа, строки и массивы, потому что, согласно документации Apple, это все, что должно быть во вспомогательной информации в PDF-файле. Бит массива не тестировался, потому что у меня нет PDF-файла с массивом в Aux Info. Если кто-то захочет проверить это для меня или ссылку на PDF-файл, в котором есть один, я с радостью протестирую это.

Сначала в заголовке класса создайте id selfClass вне тегов @interface , чтобы функции C, вызываемые CGPDFDictionaryApplyFunction , могли получить доступ к текущему классу. Также добавьте 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;
}
11
ответ дан 6 December 2019 в 22:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: