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で文字列を扱えるのは便利だ。
