無料Wikiサービス | デモページ
Linuxなどのメモ書き

PDFをJPEGに変換


概要

PDFファイルの各ページをJPEG画像に変換する。

Linux上でpdftoppmなどのツールを使うことで簡単に変換できるが、フォント周りが若干汚くなったりするため、Mac OS XでPDFKitを使って変換する。

開発環境

  • OS: Mac OS X 10.4 (PPC)
  • 環境: X-Code
  • 言語: Objective-C

変換処理

変換はPDFKitを使って読み込んだPDFファイルから各ページのオブジェクトPDFPageを取得して、以下のように変換していく。

  1. PDFPageからNSData取得
  2. NSDataからNSPDFImageRepを生成
  3. NSPDFImageRepの内容をNSImageに描画
  4. NSImageからTIFFRepresentationでTIFF表現データを取得
  5. TIFF表現からNSBitmapImageRepを生成
  6. NSBitmapImageRepからJPEGデータを生成してファイルへ書き出す

2.でPDFデータを画像に変換する際、NSPDFImageRepではなくNSBitmapImageRepに変換してしまうとこの時点でビットマップデータになってしまうため、この後画像のリサイズをすると画像が荒くなってしまう。NSPDFImageRepであればベクトル情報のままなので、3.でNSImageに変換する際画像をリサイズしても綺麗に処理される。

変換処理部分のソースは以下のとおり。

- (BOOL) _pdf2jpeg:(PDFDocument *)doc path:(NSString *)savePath file:(NSString *)filename
{
        int i;
        char basename[1024];
        char ext[100];

        filename2name([filename UTF8String], basename, sizeof(basename));
        filename2ext([filename UTF8String], ext, sizeof(ext));

        NSDictionary *propJpeg;
        propJpeg = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithFloat: 0.5],
                                NSImageCompressionFactor,
                                nil];

        int pageN = [doc pageCount];
        for (i = 0 ; i < pageN ; i++) {
                NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
                PDFPage *page = [doc pageAtIndex: i];
                NSImage *image = [self _pdf2image: page];
                if (!image) {
                        [pool release];
                        return NO;
                }

                // Bitmap画像に変換
                NSData *tiffRep = [image TIFFRepresentation];
                NSBitmapImageRep *imageRep = [[[NSBitmapImageRep alloc] initWithData:tiffRep] autorelease];
                if (!imageRep) {
                        [pool release];
                        return NO;
                }

                // Jpeg出力
                NSData       *dataJpeg;
                BOOL          bResult;
                dataJpeg = [imageRep representationUsingType: NSJPEGFileType properties:propJpeg];

                NSString *filename = [NSString stringWithFormat: @"%s/%s-%d.%s",
                                                                [savePath UTF8String], basename, i, ext];
                bResult = [dataJpeg writeToFile : filename atomically: YES];
                if (!bResult)
                        NSLog(@"ERR");

                [progressMsg setStringValue:[NSLocalizedString(@"Processing", nil)
                                stringByAppendingFormat:@"...(%d/%d)", i+1, pageN]];
                [indicator setDoubleValue:(i + 1)*100 / pageN];

                [pool release];

                if (needAbort)
                        break;
        }

        [progressMsg setStringValue:@""];

        return YES;
}

- (NSImage *)_pdf2image:(PDFPage *)page
{
        NSData *dataPage = [page dataRepresentation];

        // PDF画像 (NSBitmapImageRepだとリサイズした時に画像が荒くなる)
        NSPDFImageRep *pdfImageRep = [[[NSPDFImageRep alloc] initWithData:dataPage] autorelease];
        if (!pdfImageRep)
                return nil;

        // NSImageに書き込む
        NSSize size;    // 出力サイズ
        if (0) {
                // resizeする場合
                size.width  = 2400;
                size.height = 2400;
        } else {
                size.width  = [pdfImageRep pixelsWide];
                size.height = [pdfImageRep pixelsHigh];
        }

        NSImage *image = [[[NSImage alloc] initWithSize:size] autorelease];
        if (!image)
                return nil;
        [image lockFocus];
        [pdfImageRep drawInRect: NSMakeRect(0, 0, size.width, size.height)];
        [image unlockFocus];

        return image;
}


全ソースおよびバイナリ

バイナリ:PDF2JPEG.zip
ソースコード:PDF2JPEG_src.tgz

2008/8/1  更新 V1.2

  • 画像サイズを指定できるように修正(等倍のみ)
  • Window Close時にプロセスも終了するように修正

2008/7/4  更新 V1.1

  • PDFサイズ表示追加
  • 変換中のプログレスバー表示追加
  • 変換の中断処理追加

2008/6/27 更新  V1.0

  • ページ数が多いとメモリを浪費する問題の対策
  • 変換中の進捗表示追加
  • 変換処理のスレッド化


最終更新 2008/08/01 21:58:29 - kztomita
(2008/06/12 21:31:59 作成)