2014/02/17

popplerを使ってpdfファイルをQImageに読み込む(おまけにQimageをpdfファイルとして書き出す)

前回でインストールしたpopplerを使ってQtアプリでpdfファイルを読み込む。 今回はpdfといってもページ=画像ファイルなのでわりと簡単。


#include <poppler/qt4/poppler-qt4.h>


openPdfFile(QString fileName){
  Poppler::Document *doc = Poppler::Document::load(fileName);
  if(doc == 0) return;

  for(int pageNum = 0; pageNum < doc->numPages(); pageNum++){
    Poppler::Page *pdfPage = doc->page(pageNum);
    
    QImage image = pdfPage->renderToImage();
    // このimageを使って描画処理等を行う

    // pdfPageは使い終わったらdeleteが必要
    delete pdfPage;
  }
  // docは使い終わったらdeleteが必要
  delete doc;
}




一方でpdf出力に関しては、これもテキストを出力するのでなければQt自体がもっているpdf出力を使えるので
以下のようにすればQImageをページいっぱいに描画したpdfが出力できる。



exportPagesAsPdf(QString fileName){

  // QtはQPrinterをつかってpdfファイル出力ができる
  QPrinter printer(QPrinter::HighResolution);
  printer.setOutputFormat(QPrinter::PdfFormat);
  printer.setPageMargins(0, 0, 0, 0, QPrinter::Point);// margin 0にして縁なしにする
  printer.setOutputFileName(fileName);
  const int dpi = 72;
  printer.setResolution(dpi);
  QPainter painter;

  for(int i = 0; i < mPages.size(); i++){
      QImage image = mPages[i].image();

      // 仮に毎ページサイズが変わってもOKにしてる
      printer.setPaperSize(image.size(), QPrinter::Point);
      if(i == 0){
          painter.begin(&printer);// 最初のページはnewPage()をいれてはいけないので特別処理
      }
      else{
          printer.newPage();// サイズを指定した後にnewPage()を呼ぶとそのサイズのPageが挿入される
      }
      painter.drawImage(0, 0, image);
  }
}




dpiをなぜ72にしたらいいのか実はちょっとわかってないんだが、popplerのdocumentのPage::renderToImage()のdpiのデフォルト引数が72.0だったので、一緒にしたらいいんじゃないかなぁと思ったらうまくいった。

QPrinterのAPIをみるとテキストをセットするようなものはないので、
OCRしたテキストをpdfに埋め込みたい時には多分QPrinterでは無理なんじゃないかな?
きっとHandling PDFにあるようにほかのthird partyライブラリを 使えばできるんだろうけど。今回はまぁこの辺で。


popplerをhomebrewを使ってインストール

最近、ドキュメントスキャナを購入してから細々と自炊して本・マンガ本の省スペース化を図っている。
WindowsはeTritranという素晴らしいソフトがあるが、
Macで同じような事(簡単なトーンカーブ補正、ページ回転等々)をやろうとした時に、
ちょうどいいソフトが見つからなかったので、機能は制限されるがQtを使って自分で作ってたりする → こんな感じePage

今の所zip(jpegのzip化)の解凍はquazipを使って読み込むことができるようになったんだが、
段々欲が出てきてpdfも読み書きしたくなってきた。

ということでQtにpdfを読み書きする方法があるのかと探すと・・どうもなさそう。
詳細はHandling_PDFに書かれているが、
出力する事はQPrinterを使ってできるみたい。でも読む方はQtにはなくて3rd partyのライブラリを使わないといけないみたい。

こんな感じで3つほど紹介されてる。


今回は自炊した漫画本をメインで考えてるので出力はQPrinterを使って、読み込む機能があるpopplerを使う事にする。 Qt wrapperがあってQtとの親和性も高そう。
で、popplerをソースからコンパイルしてもいいんだが、freetype2が必要だったりlibpngやlibopenjpegが必要だったり 結構依存ライブラリがおおい。なので、この際今まで使った事がなかったhomebrewを使って入れてみようかなと。
homebrewとそのインストールついてはパッケージ管理システム Homebrewなど、いい参考サイトがあるのでそちらをみてもらうとして。
コマンド一つでインストールできる所が美しい・・。

 $brew update
 $brew install poppler --with-qt4


とすると、デフォルトでは/usr/local/Cellar/以下にpopplerと依存ファイル(qt4も)インストールしてくれます。 楽だなー。
なので、.proファイルに以下を追加する事でプログラム中でpopplerを使えるようになります。

LIBS += -lpoppler-qt4

INCLUDEPATH += /usr/local/Cellar/poppler/0.24.5/include

DEPTHDPATH += /usr/local/Cellar/poppler/0.24.5/lib


具体的な使い方は次回で。