Bibliothèque basée sur Qt "Poppler" qui vous permet de lire rapidement des PDF sous forme d'images en C ++ ou Python

Ce n'est pas surprenant. Bibliothèque PDF.

Je pensais qu'il y aurait autant de bibliothèques que je pourrais facilement lire et créer des images PDF, mais de manière inattendue, je n'ai pas pu en trouver une qui soit facile à utiliser. Cependant, la bibliothèque appelée Poppler écrite avec Qt était assez bonne, alors j'ai essayé de l'utiliser. Poppler-qt4 (C++) http://people.freedesktop.org/~aacid/docs/qt4/ python-poppler-qt4 https://pypi.python.org/pypi/python-poppler-qt4/

De plus, la documentation de Poppler est ici. Tout d'abord, lisez Type de document pour découvrir ce que vous pouvez faire.

Il existe également une version Qt5, mais cette fois j'ai utilisé la version Qt4. Certains ont été écrits à la fois en C ++ et en Python. Python a utilisé Python3.

Tout le code posté ici est posté sur github.

La bonne chose à propos de Poppler

Utilisons

En démo, j'ai fait ce qui suit.

  1. Enregistrez le PDF en tant qu'image de chaque page (Python uniquement)
  2. Script d'extraction de texte à partir de PDF (Python uniquement)
  3. Visionneuse PDF super simple (implémentée en C ++ et Python. Seule la version C ++ est présentée dans l'article)

Sauvegarder l'image

Charger avec doc = Poppler.Document.load (chemin). Notez que si vous n'écrivez pas doc.setRenderHint (Poppler.Document.TextAntialiasing), la sortie sera très désordonnée. Après le chargement, récupérez l'objet Page avec page = doc.page (i). Les numéros de page commencent à zéro. Si ʻimage = page.renderToImage () , l'image sera renvoyée par le [type QImage] de Qt (http://doc.qt.io/qt-4.8/qimage.html). Les images peuvent être sauvegardées avec ʻimage.save () .

Écrit en Python. Si vous le souhaitez, je pense qu'il est facile de le rendre C ++.

dump_image.py


import sys
import os.path
from contextlib import closing

from PyQt4 import QtCore
from popplerqt4 import Poppler

FORMAT = 'PNG'
EXT = '.png'

def dump_image(path):
    doc = Poppler.Document.load(path)
    doc.setRenderHint(Poppler.Document.TextAntialiasing)
    filename_fmt = os.path.splitext(path)[0] + '_{0}' + EXT
    for n,page in ((i+1, doc.page(i)) for i in range(doc.numPages())):
        page.renderToImage().save(filename_fmt.format(n), FORMAT)

if __name__ == '__main__':
    app = QtCore.QCoreApplication(sys.argv)
    if len(sys.argv) != 2:
        print('Usage: {0} pdf_path'.format(sys.argv[0]))
    else:
        dump_image(sys.argv[1])
    sys.exit(0)

Extrayons le texte

Pour l'extraction de texte, je pense qu'il existe de nombreuses bibliothèques en plus de Poppler. Je peux le faire pour le moment. page.textList () retourne une liste d'objets Textbox avec des mots, donc nous bouclons chacun d'eux.

dump_text.py


import sys

from PyQt4 import QtCore
from popplerqt4 import Poppler

def dump_text(path):
    doc = Poppler.Document.load(path)
    for n,page in ((i+1, doc.page(i)) for i in range(doc.numPages())):
        print('\n-------- Page {0} -------'.format(n))
        for txtbox in page.textList():
            print(txtbox.text(), end=' ')

if __name__ == '__main__':
    app = QtCore.QCoreApplication(sys.argv)
    if len(sys.argv) != 2:
        print('Usage: {0} pdf_path'.format(sys.argv[0]))
    else:
        dump_text(sys.argv[1])
    sys.exit(0)

Faisons un visualiseur PDF (C ++)

Il s'avère que Poppler peut convertir des pages en images de type QImage. Vous pouvez également demander à QPainter de dessiner la page. Vous pouvez utiliser QPainter, mais cette fois, je vais prendre le type QImage, le convertir en type QPixmap et l'afficher sur le widget QLabel (PdfWidget qui en hérite).

Je ne voulais pas faire quelque chose de trop élaboré, donc je n'avais pas d'interface utilisateur de lecture de fichiers. Le chemin du fichier est spécifié dans le constructeur du widget et il est chargé. Je pense qu'il aurait été préférable de le redimensionner en fonction de la taille du widget, mais je ne l'ai pas fait cette fois.

pdfwidget.h


#include <QLabel>
#include <QString>

namespace Poppler{
        class Document;
};

class PdfWidget : public QLabel{
        Q_OBJECT
public:
        PdfWidget(QString path, QWidget *parent = 0);
public slots:
        void next_page();
        void prev_page();
private:
        void load_current_page();
        int n_pages;
        int current_page;
        QString path;
        Poppler::Document *doc;
};

pdfwidget.cpp


#include "pdfwidget.h"
#include <poppler-qt4.h>
#include <QAction>
#include <QPixmap>

PdfWidget::PdfWidget(QString path, QWidget *parent)
                : QLabel(parent), path(path)
{
        doc = Poppler::Document::load(path);
        doc->setRenderHint(Poppler::Document::TextAntialiasing);
        n_pages = doc->numPages();
        current_page = 0;
        load_current_page();

        QAction *next_page = new QAction("Next Page", this);
        next_page->setShortcut(Qt::Key_Right);
        connect(next_page, SIGNAL(triggered()), this, SLOT(next_page()));
        addAction(next_page);

        QAction *prev_page = new QAction("Prev Page", this);
        prev_page->setShortcut(Qt::Key_Left);
        connect(prev_page, SIGNAL(triggered()), this, SLOT(prev_page()));
        addAction(prev_page);
}

void PdfWidget::next_page()
{
        current_page++;
        if(current_page >= n_pages) current_page = 0;
        load_current_page();
}

void PdfWidget::prev_page()
{
        if(current_page) current_page--;
        else current_page = n_pages - 1;
        load_current_page();
}

void PdfWidget::load_current_page()
{
        setPixmap(QPixmap::fromImage(doc->page(current_page)->renderToImage()));
        setWindowTitle(QString("%1/%2 - %3").arg(current_page+1)
                                            .arg(n_pages).arg(path));
}

Pour le moment, j'essaye d'aller à la page suivante / page précédente avec la droite / gauche du clavier.

Résumé

Pour autant que je sache, il n'y a pas beaucoup de bibliothèques capables de convertir des PDF en images, que ce soit en C ++ ou en Python. J'ai présenté Poppler comme une bibliothèque facile à utiliser sur une multi-plateforme, même si ce n'est pas tellement.

Cela va bien avec Qt, donc c'est très facile à utiliser lorsque vous souhaitez gérer des PDF avec une interface graphique.

Recommended Posts

Bibliothèque basée sur Qt "Poppler" qui vous permet de lire rapidement des PDF sous forme d'images en C ++ ou Python
À propos de psd-tools, une bibliothèque capable de traiter des fichiers psd en Python
Fonction Eval () qui calcule une chaîne de caractères comme expression en python
[Python3] Code qui peut être utilisé lorsque vous souhaitez découper une image dans une taille spécifique
J'ai enregistré PyQCheck, une bibliothèque qui peut effectuer QuickCheck avec Python, dans PyPI.
Comment utiliser la bibliothèque C en Python
Utilisez Python pour une sortie formatée telle que C / C ++ printf
Créer un environnement qui utilise Python avec Eclipse
Comment utiliser la bibliothèque d'images Python dans la série python3
Lire les données de la table dans un fichier PDF avec Python
Créer une image avec des caractères avec python (japonais)
Mettre en place un serveur FTP qui peut être créé et détruit immédiatement (en Python)