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

Adsense

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


最終更新 2012/05/05 22:16:15 - kztomita
(2012/05/05 22:16:15 作成)