2012-05-01 1 views
0

Я пишу парсер PDF для работы, и мы используем Core Graphics для чтения во всех данных с обратными вызовами, а затем записываем его с Lib Haru, потому что нашему клиенту необходимо написать «реальные» аннотации, и CG не может этого сделать.CGPDF - Сохранение изображений с помощью фильтра FlateDecode

Ну, я дошел до того, что получаю изображения (и сохраняю их в файле, чтобы убедиться, что я делаю это прямо до того, как начну рисовать их), и я столкнулся с проблемой , Я получаю все 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», но всякий раз, когда фильтр «FlateDecode», сохраненное изображение повреждено и не открывается.

Я прочитал в this post, что CGPDFStreamCopyData может декодировать текст с FlateDecode (все пути к нижней части поста в комментариях), но есть только три формата данных в CGPDFDataFormats, и ни один из них не работает.

Я считаю, что у меня также проблемы с текстом, закодированным с помощью FlatDecode. Есть ли у кого-нибудь предложения по поводу того, как это сделать? Конечно, CGPDF имеет что-то, что обрабатывает это, поскольку оно появляется почти в каждом PDF-файле, который я пытался открыть (хотя я не смог его найти).

Edit: Я читал в нескольких местах, которые я мог бы распаковать его с помощью 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]; 

Код Ждут» t бросать любые исключения, когда я его запускал, но полученные изображения все еще не читались.

ответ

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 
} 

PNG изображение не поддерживается на все стандарт PDF, так что вы никогда не получите правильный файл PNG из потока данных изображения. Возможные варианты: JPEG, JPEG2K и необработанные изображения (подробности см. В спецификации).

Кварц обрабатывает сжатие zlib прозрачно, поэтому вы никогда не получите данные, сжатые zlib.