一点点背景:我正在向一个已经存在的pdf文件中添加一个图像。我发现没有办法只是添加一个页面到它,你必须重新创建整个pdf,然后删除旧的,然后移动新的。(如果这是错误的,请告诉我,它会给我带来很多头痛。)我已经完成了这一部分,但我现在试图复制辅助信息(标题,作者,钥匙等)。问题是有太多的类型问题,我现在使用的方法是获取CGPDFDocumentRef的CGPDFDictionaryRef,然后调用CGPDFDictionaryApplierFunction。在我传递它的C函数中,我将每个键提取到一个NSMutableDictionary,这样我就可以对值做一些事情,而不是将它们锁定在这种糟糕的CGPDF格式中。
所以基本上我的问题是:有没有更好的方法来做到这一点?我一直盯着这么多的文档文件,我无法想象会有什么遗漏,但我真的希望我有,因为我需要做的解决办法的数量变得荒谬。
发布于 2010-08-11 16:03:32
我已经完成了我的解决方案。我仍然想知道是否有更好的方法来做到这一点,所以如果你知道一个或有任何建议,我愿意尝试他们。
注意:我只检查bools、int、string和数组,因为根据Apple的文档,在PDF中应该包含在辅助信息中的所有内容。数组位是未经测试的,因为我在辅助信息中没有带有数组的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;
}发布于 2010-08-11 00:16:06
您可以通过绘制到CGPDFContext来完成您所描述的内容,但是如果您有一个复杂的PDF,您可能正在尝试一些超出API意图的内容。你可以看看PDF规范的3.4节,看看你要进入什么。
https://stackoverflow.com/questions/3453874
复制相似问题