PDFをJPEGに変換(コマンドライン)
PDFをJPEGに変換のコメント欄でqqさんからあった質問への回答。
以下のソースは、X-CodeのCommand Line Toolプロジェクト(TypeはFoundation)で動作するものです。
pdf2jpg()関数が指定PDFファイルの指定ページをjpgファイルに変換する関数になります。
pdf2jpg()の引数
char *pdfPath PDFファイルのパス
uint32 page PDFファイルのページ番号(0-)
char *jpgFile 出力先のjpgファイル名
uint32 width jpgの出力幅(Pixel)。高さは縦横比を維持するように自動計算。0を指定した場合は等倍になる。
プロジェクトのmain.m
#import <Foundation/Foundation.h> #import <Quartz/Quartz.h> static NSImage *pdf2image(PDFPage *page, uint32 width); static bool pdf2jpg(char *pdfPath, uint32 page, char *jpgFile, uint32 width); NSImage *pdf2image(PDFPage *page, uint32 width) { NSData *dataPage = [page dataRepresentation]; NSPDFImageRep *pdfImageRep = [[NSPDFImageRep alloc] initWithData:dataPage]; if (!pdfImageRep) return nil; NSSize size; size.width = [pdfImageRep pixelsWide]; size.height = [pdfImageRep pixelsHigh]; if (width && size.width) { size.height = width * size.height / size.width; size.width = width; } NSImage *image = [[[NSImage alloc] initWithSize:size] autorelease]; if (!image) { [pdfImageRep release]; return nil; } [image lockFocus]; [pdfImageRep drawInRect: NSMakeRect(0, 0, size.width, size.height)]; [image unlockFocus]; [pdfImageRep release]; return image; } // page: 0- bool pdf2jpg(char *pdfPath, uint32 page, char *jpgFile, uint32 width) { NSString *strPdfPath = [NSString stringWithCString:pdfPath encoding:NSASCIIStringEncoding]; PDFDocument *pdfDoc = [[[PDFDocument alloc] initWithURL: [NSURL fileURLWithPath: strPdfPath]] autorelease]; if (!pdfDoc) return nil; PDFPage *pdfPage = [pdfDoc pageAtIndex: page]; if (!pdfPage) return nil; NSImage *image = pdf2image(pdfPage, width); NSData *tiffRep = [image TIFFRepresentation]; NSBitmapImageRep *imageRep = [[[NSBitmapImageRep alloc] initWithData:tiffRep] autorelease]; if (!imageRep) return nil; NSDictionary *propJpeg; propJpeg = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithFloat: 0.5], NSImageCompressionFactor, nil]; // ファイル名によらず出力は問答無用でjpgで。 NSData *dataJpeg; BOOL bResult; dataJpeg = [imageRep representationUsingType: NSJPEGFileType properties:propJpeg]; NSString *filename = [NSString stringWithCString:jpgFile encoding:NSASCIIStringEncoding]; bResult = [dataJpeg writeToFile : filename atomically: YES]; if (!bResult) return nil; return true; } int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // 変換関数呼び出し。とりあえず引数は固定。 if (!pdf2jpg("/Users/tomita/tmp/pdf2jpg/pdf2jpg/PDF32000_2008.pdf", 2, "test.jpg", 1200)) { NSLog(@"Error"); return 1; } NSLog(@"OK"); [pool drain]; return 0; }
TODO
- コマンドライン引数を真面目に解析してpdf2jpg()に渡す。
- pdf2jpg()内で生成するPDFDocumentはautoreleaseのため、同じPoolで繰り返し呼び出していると、メモリ使用量が膨れ上がるので、ちゃんとreleaseするようにする。
- jpg以外のファイル出力への対応
コマンドラインツールでCocoaを使ったのは初めてだが、C++でSTLを使うようなのりでNSStringで文字列を扱えるのは便利だ。