【问题标题】:CGPDF - Saving images with FlateDecode FilterCGPDF - 使用 FlateDecode 过滤器保存图像
【发布时间】:2012-05-01 17:41:47
【问题描述】:

我正在为工作编写一个 PDF 解析器,我们使用 Core Graphics 通过回调读取所有数据,然后使用 Lib Haru 将其写出,因为我们的客户需要写出“真实”的注释和 CG做不到。

好吧,我已经到了获取图像的地步(并将它们保存到一个文件中,以确保在开始绘制它们之前我正在这样做)并且我遇到了一个问题。我正在从 Resource 字典中获取所有 Image XObjects,然后尝试使用此代码将它们保存出来

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];                

NSData *imageFileData = (NSData *)CGPDFStreamCopyData(objectStream, CGPDFDataFormatRaw);

NSString *fileName = [NSString stringWithFormat:@"%@/%s.png", documentsDir, name];
[imageFileData writeToFile:fileName atomically:YES];

objectStream 使用 CGPDFDictionaryGetStream 来提取 XObject。好吧,当Filter为“DCTDecode”时它可以正常工作,但是当Filter为“FlateDecode”时,保存的图像已损坏并且无法打开。

我在this post 中读到,CGPDFStreamCopyData 可以使用 FlateDecode 解码文本(一直到 cmets 中的帖子底部),但是 CGPDFDataFormats 中只有 3 种数据格式,并且它们都不起作用。

我相信我也遇到了使用 FlatDecode 编码的文本的问题。有没有人对如何解码这个有任何建议?当然 CGPDF 有一些东西可以处理这个问题,因为它几乎出现在我尝试打开的每个 pdf 中(尽管我无法找到它)。

编辑:我在一些可以使用 zlib 解压缩的地方阅读,所以我尝试了这段代码,我可以找到关于如何做到这一点的代码:

            NSData* uncompressedImageData;
            if ([imageFileData length] == 0) 
                uncompressedImageData = imageFileData;
            else
            {                
                z_stream strm;
                strm.zalloc = Z_NULL; 
                strm.zfree = Z_NULL; 
                strm.opaque = Z_NULL; 
                strm.total_out = 0; 
                strm.next_in=(Bytef*)[imageFileData bytes]; 
                strm.avail_in = [imageFileData length];

                // Compresssion Levels: // Z_NO_COMPRESSION // Z_BEST_SPEED // Z_BEST_COMPRESSION // Z_DEFAULT_COMPRESSION
                if (deflateInit(&strm, Z_DEFAULT_COMPRESSION) != Z_OK) 
                    uncompressedImageData = nil;

                NSMutableData *compressed = [NSMutableData dataWithLength:16384]; // 16K chuncks for expansion
                do 
                {
                    if (strm.total_out >= [compressed length]) 
                        [compressed increaseLengthBy: 16384];

                    strm.next_out = [compressed mutableBytes] + strm.total_out; strm.avail_out = [compressed length] - strm.total_out;
                    deflate(&strm, Z_FINISH);
                } 
                while (strm.avail_out == 0);

                deflateEnd(&strm);
                [compressed setLength: strm.total_out]; 

                uncompressedImageData = [NSData dataWithData: compressed]; 
            }

            if(uncompressedImageData != nil)
                [uncompressedImageData writeToFile:fileName atomically:YES];

代码在我运行时没有抛出任何异常,但生成的图像仍然不可读。

【问题讨论】:

    标签: iphone objective-c c pdf cgpdf


    【解决方案1】:

    您对CGPDFStreamCopyData 的使用似乎表明您在那里有一个误解:您没有设置您想要的格式,该函数将其设置为它在流中遇到的格式。一个典型的用途是:

    CGPDFDataFormat format;
    CGPDFStreamCopyData(objectStream, &format);
    if (format == CGPDFDataFormatRaw) {
        //handle raw data...
    } else if (format == CGPDFDataFormatJPEGEncoded) {
        //handle jpeg data...
    } else if (format == CGPDFDataFormatJPEG2000) {
        //handle jpeg 2000 data
    }
    

    PDF 标准根本不支持 PNG 图像,因此您永远无法从图像数据流中获得有效的 PNG 文件。选项包括 JPEG、JPEG2K 和原始图像(有关这些的详细信息,请参阅规范)。

    Quartz 透明地处理 zlib 压缩,因此您永远不会自己获得 zlib 压缩数据。

    【讨论】:

      猜你喜欢
      • 2013-03-18
      • 2017-11-29
      • 2021-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-05
      相关资源
      最近更新 更多