PDFをJPEGに変換
Rev.8を表示中。最新版はこちら。
概要
PDFファイルの各ページをJPEG画像に変換する。
Linux上でpdftoppmなどのツールを使うことで簡単に変換できるが、フォント周りが若干汚くなったりするため、Mac OS XでPDFKitを使って変換する。
開発環境
- OS: Mac OS X 10.4 (PPC)
- 環境: X-Code
- 言語: Objective-C
変換処理
変換はPDFKitを使って読み込んだPDFファイルから各ページのオブジェクトPDFPageを取得して、以下のように変換していく。
- PDFPageからNSData取得
- NSDataからNSPDFImageRepを生成
- NSPDFImageRepの内容をNSImageに描画
- NSImageからTIFFRepresentationでTIFF表現データを取得
- TIFF表現からNSBitmapImageRepを生成
- 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];
// docはPDFDocumentオブジェクト
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];
// Bitmap画像に変換
NSData *tiffRep = [image TIFFRepresentation];
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:tiffRep];
if (!imageRep) {
[image 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");
[textMsg setStringValue:[NSLocalizedString(@"Processing", nil)
stringByAppendingFormat:@"...(%d/%d)", i+1, pageN]];
[image release];
[imageRep release];
[pool release];
}
[textMsg setStringValue:@""];
return YES;
}
- (NSImage *)_pdf2image:(PDFPage *)page
{
NSData *dataPage = [page dataRepresentation];
// PDF画像 (NSBitmapImageRepだとリサイズした時に画像が荒くなる)
NSPDFImageRep *pdfImageRep = [[NSPDFImageRep alloc] initWithData:dataPage];
// 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];
[image lockFocus];
[pdfImageRep drawInRect: NSMakeRect(0, 0, size.width, size.height)];
[image unlockFocus];
[pdfImageRep release];
return image;
}
全ソースおよびバイナリ
バイナリ:PDF2JPEG.zipソースコード:PDF2JPEG_src.tgz
6/27 更新 V1.0
- ページ数が多いとメモリを浪費する問題の対策
- 変換中の進捗表示追加
- 変換処理のスレッド化
画像サイズの指定
中断ボタン
