Ich dachte, es gäbe so viele Bibliotheken, wie ich PDFs leicht lesen und abbilden könnte, aber unerwartet konnte ich keine finden, die einfach zu bedienen war. Die mit Qt geschriebene Bibliothek namens Poppler war jedoch ziemlich gut, also habe ich versucht, sie zu verwenden. Poppler-qt4 (C++) http://people.freedesktop.org/~aacid/docs/qt4/ python-poppler-qt4 https://pypi.python.org/pypi/python-poppler-qt4/
Popplers Dokumentation ist auch hier. Lesen Sie zunächst unter Dokumenttyp nach, was Sie tun können.
Es gibt auch eine Qt5-Version, aber diesmal habe ich die Qt4-Version verwendet. Einige wurden sowohl in C ++ als auch in Python geschrieben. Python verwendete Python3.
Der gesamte hier veröffentlichte Code ist auf github veröffentlicht.
Als Demo habe ich Folgendes gemacht.
Laden Sie mit doc = Poppler.Document.load (path)
.
Beachten Sie, dass die Ausgabe sehr unübersichtlich ist, wenn Sie nicht "doc.setRenderHint (Poppler.Document.Text Antialiasing)" schreiben.
Rufen Sie nach dem Laden das Page-Objekt mit page = doc.page (i)
ab. Seitenzahlen beginnen bei Null.
Wenn Sie "image = page.renderToImage ()" festlegen, wird das Bild von Qts QImage-Typ zurückgegeben.
Bilder können mit image.save ()
gespeichert werden.
Geschrieben in Python. Wenn Sie möchten, denke ich, ist es einfach, es C ++ zu machen.
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)
Für die Textextraktion gibt es neben Poppler viele Bibliotheken. Ich kann es vorerst tun. page.textList () gibt eine Liste von Textbox-Objekten mit Wörtern zurück, sodass wir jedes einzelne durchlaufen.
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)
Es stellt sich heraus, dass Poppler Seiten in Bilder vom Typ QImage konvertieren kann. Sie können QPainter auch die Seite zeichnen lassen. Sie können QPainter verwenden, aber dieses Mal werde ich den QImage-Typ verwenden, ihn in den QPixmap-Typ konvertieren und ihn im QLabel-Widget (PdfWidget, das ihn erbt) anzeigen.
Ich wollte nichts zu aufwändig machen, also hatte ich keine Benutzeroberfläche zum Lesen von Dateien. Der Dateipfad wird im Konstruktor des Widgets angegeben und geladen. Ich denke, es wäre besser gewesen, die Größe entsprechend der Widget-Größe zu ändern, aber diesmal habe ich es nicht getan.
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));
}
Vorerst versuche ich, mit der rechten / linken Seite der Tastatur zur nächsten Seite / vorherigen Seite zu wechseln.
Soweit ich weiß, gibt es weder in C ++ noch in Python viele Bibliotheken, die PDF-Dateien in Bilder konvertieren können. Ich habe Poppler als benutzerfreundliche Bibliothek auf mehreren Plattformen eingeführt, auch wenn es nicht so viel ist.
Es passt gut zu Qt und ist daher sehr einfach zu verwenden, wenn Sie PDF mit GUI verarbeiten möchten.
Recommended Posts