1

仕事用に 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 を抽出しています。フィルターが「DCTDecode」の場合は正常に動作しますが、フィルターが「FlateDecode」の場合は常に、保存された画像が破損して開きません。

この投稿で、CGPDFStreamCopyData は FlateDecode でテキストをデコードできることを読みました(コメントの投稿の最後まで) が、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];

コードを実行しても例外はスローされませんでしたが、結果の画像はまだ判読できませんでした。

4

1 に答える 1

3

の使用は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、および raw 画像です (これらの詳細については、仕様を参照してください)。

Quartz は zlib 圧縮を透過的に処理するため、zlib 圧縮されたデータを自分で取得することはありません。

于 2012-05-02T14:36:19.520 に答える