使用CoreGraphics修改pdf元数据颜色空间

时间:2012-11-29 14:50:45

标签: pdf core-graphics quartz-graphics color-space

我试图改变pdf文件图像对象的颜色空间,但第一个问题是我在pdf元数据中找不到ICC颜色配置文件。

Metadata中的所有内容都是一个包含2个组件的数组:

ColorSpace :
    Name value: ICCBased
    Stream value (null) 

当我将Stream解析为字典时:

Color Space Name ICCBased
  Filter :
    Name value: FlateDecode
  Length :
   integer value: 389757 
  N :
   integer value: 4 
  Range :
   ARRAY with value:
    integer value: 0 
    integer value: 1 
    integer value: 0 
    integer value: 1 
    integer value: 0 
    integer value: 1 
    integer value: 0 
    integer value: 1 

但我无法在元数据中找到图像颜色空间中使用的ICC配置文件数据,您可以使用acrobat查看:

enter image description here

顺便说一下,如果你对如何通过coreGraphics获取pdf文件的元数据感兴趣,我在这里放了一些代码:

  

...

     

CGPDFDocumentRef pdfDocument = CGPDFDocumentCreateWithURL(pdfURL);

     

CGPDFPageRef page = CGPDFDocumentGetPage(pdfDocument,pageNumber);

     

CGPDFContentStreamRef contentStream =

     

CGPDFContentStreamCreateWithPage(页); CGPDFOperatorTableRef

     

operatorTable = CGPDFOperatorTableCreate();

     

CGPDFOperatorTableSetCallback(operatorTable,“Do”,& op_Do);

     

CGPDFScannerRef contentStreamScanner =

     

CGPDFScannerCreate(contentStream,operatorTable,NULL);

     

CGPDFScannerScan(contentStreamScanner);

     

...

然后回调:

  

static void op_Do(CGPDFScannerRef s,void * info){

     

CGPDFObjectRef imageObject = CGPDFContentStreamGetResource(cs,“XObject”,imageLabel);

     

CGPDFStreamRef xObjectStream;

if (CGPDFObjectGetValue(imageObject, kCGPDFObjectTypeStream, &xObjectStream)) {

    CGPDFDictionaryRef xObjectDictionary = CGPDFStreamGetDictionary(xObjectStream);

    const char *subtype;

    CGPDFDictionaryGetName(xObjectDictionary, "Subtype", &subtype);

    if (strcmp(subtype, "Image") == 0) {

        NSString *imageID = [NSString stringWithCString: imageLabel encoding: NSASCIIStringEncoding];

        CGPDFDictionaryApplyFunction(xObjectDictionary, ListDictionaryObjects, NULL);
     

if(CGPDFDictionaryGetName(xObjectDictionary,“ColorSpace”,& colorSpaceName)){

            fprintf(stdout,"Color Space Name %s\n", colorSpaceName);
     

}否则{

            //Getting Color space array
            CGPDFArrayRef objectArray;

            CGPDFDictionaryGetArray(xObjectDictionary, "ColorSpace", &objectArray);
            //getting each array position             
            CGPDFStreamRef colorsSpaceStream;

            CGPDFArrayGetName(objectArray, 0, &colorSpaceName);

            fprintf(stdout,"Color Space Name %s\n", colorSpaceName);

            CGPDFArrayGetStream(objectArray, 1, &colorsSpaceStream);

            CGPDFDictionaryRef dictionary = CGPDFStreamGetDictionary(colorsSpaceStream);

            CGPDFDictionaryApplyFunction(dictionary, ListDictionaryObjectsLow, NULL);
     

}

     

...

最后在ListDictionaryObjects函数中,我浏览了字典对象:

  

void ListDictionaryObjects(const char * key,CGPDFObjectRef object,void * info){       fprintf(stdout,“%s:\ n”,键);

CGPDFObjectType type = CGPDFObjectGetType(object);
switch (type) {
    case kCGPDFObjectTypeDictionary: {
        CGPDFDictionaryRef objectDictionary;
        if (CGPDFObjectGetValue(object, kCGPDFObjectTypeDictionary, &objectDictionary)) {
            fprintf(stdout," Dictionary value with: %zd elements\n", CGPDFDictionaryGetCount(objectDictionary));
            CGPDFDictionaryApplyFunction(objectDictionary, ListDictionaryObjectsLow, NULL);
        }
    }
        break;
    case kCGPDFObjectTypeInteger: {
        CGPDFInteger objectInteger;
        if (CGPDFObjectGetValue(object, kCGPDFObjectTypeInteger, &objectInteger)) {
           fprintf(stdout," integer value: %ld \n", (long int)objectInteger);
        }

    }
    break;
    case kCGPDFObjectTypeReal:{
        CGPDFReal objectReal;
        if (CGPDFObjectGetValue(object, kCGPDFObjectTypeReal, &objectReal)){
            fprintf(stdout," real value: %5.2f\n", objectReal);
        }
    } ...

3 个答案:

答案 0 :(得分:1)

PDF规范中描述了您所看到的内容: http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf

查找定义基于ICC的色彩空间的第8.6.5.5节 - 您要查找的数据包含在您粘贴在邮件顶部的流中。它不易识别,因为它已被Flate编码(ZIP编码)。

问题是你想要完成什么?如果您只想丢弃这个基于ICC的颜色空间并创建一个新颜色空间,则无需查找此数据,只需创建一个新的颜色空间对象并使图像引用您的新对象。

要更改现有的ICC配置文件(通常是坏主意),您必须解压缩流数据,调整要调整的内容并重新重新压缩。

答案 1 :(得分:1)

通过使用ColorSync Utility创建Quartz Filter,可以为某个颜色空间的所有对象分配新的颜色配置文件(即不更改对象中的值)。

2005年Mac开发人员库中关于“ColorSync on Mac OS X”的技术说明:

  

Quartz过滤器目前只能通过各种Mac OS X系统构建的实用程序和应用程序使用。但是,即将推出一套新的API。

但我在Apple的开发人员文档中找不到任何其他提及Quartz Filters的内容。

我知道这不是非常有帮助,但也许它会给你一些暗示。

修改:请参阅此answer to "Apply a Quartz filter while saving PDF under Mac OS X 10.6.3"

答案 2 :(得分:0)

以下是步骤:

1-使用ColorSync实用程序创建Quartz过滤器并将其另存为.qfilter文件

2-使用以下代码将此过滤器应用于您的pdf文件:

PDFDocument *pdf = [[PDFDocument alloc]initWithURL:[NSURL fileURLWithPath:@"_pdfURL_"]];

NSDictionary *dict = [[NSDictionary alloc]initWithObjectsAndKeys:[QuartzFilter quartzFilterWithURL:[NSURL fileURLWithPath:@"_myFilter.qfilter_"]], @"QuartzFilter", nil]; 

[pdf writeToFile:@"_pdfFilePath_" withOptions:dict];
相关问题