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.
En démo, j'ai fait ce qui suit.
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)
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)
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.
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