diff --git a/Pdf4QtLib/sources/pdfcms.h b/Pdf4QtLib/sources/pdfcms.h index f3cb68e..380a1a0 100644 --- a/Pdf4QtLib/sources/pdfcms.h +++ b/Pdf4QtLib/sources/pdfcms.h @@ -250,7 +250,7 @@ public: using PDFCMSPointer = QSharedPointer; -class PDFCMSGeneric : public PDFCMS +class PDF4QTLIBSHARED_EXPORT PDFCMSGeneric : public PDFCMS { public: explicit inline PDFCMSGeneric() = default; diff --git a/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.cpp b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.cpp index 62a8856..1f16876 100644 --- a/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.cpp +++ b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.cpp @@ -20,26 +20,35 @@ #include "pdfwidgetutils.h" #include "pdfdocumentwriter.h" +#include "pdfimage.h" #include "pdfdbgheap.h" +#include "pdfexception.h" #include #include #include #include +#include namespace pdfviewer { -PDFCreateBitonalDocumentDialog::PDFCreateBitonalDocumentDialog(const pdf::PDFDocument* document, QWidget* parent) : +PDFCreateBitonalDocumentDialog::PDFCreateBitonalDocumentDialog(const pdf::PDFDocument* document, + const pdf::PDFCMS* cms, + QWidget* parent) : QDialog(parent), ui(new Ui::PDFCreateBitonalDocumentDialog), m_document(document), + m_cms(cms), m_createBitonalDocumentButton(nullptr), m_conversionInProgress(false), m_processed(false) { ui->setupUi(this); + m_classifier.classify(document); + m_imageReferences = m_classifier.getObjectsByType(pdf::PDFObjectClassifier::Image); + m_createBitonalDocumentButton = ui->buttonBox->addButton(tr("Process"), QDialogButtonBox::ActionRole); connect(m_createBitonalDocumentButton, &QPushButton::clicked, this, &PDFCreateBitonalDocumentDialog::onCreateBitonalDocumentButtonClicked); connect(ui->automaticThresholdRadioButton, &QRadioButton::clicked, this, &PDFCreateBitonalDocumentDialog::updateUi); @@ -48,6 +57,8 @@ PDFCreateBitonalDocumentDialog::PDFCreateBitonalDocumentDialog(const pdf::PDFDoc pdf::PDFWidgetUtils::scaleWidget(this, QSize(640, 380)); updateUi(); pdf::PDFWidgetUtils::style(this); + + loadImages(); } PDFCreateBitonalDocumentDialog::~PDFCreateBitonalDocumentDialog() @@ -73,6 +84,72 @@ void PDFCreateBitonalDocumentDialog::onCreateBitonalDocumentButtonClicked() updateUi(); } +void PDFCreateBitonalDocumentDialog::loadImages() +{ + QSize iconSize(QSize(256, 256)); + ui->imageListWidget->setIconSize(iconSize); + QSize imageSize = iconSize * ui->imageListWidget->devicePixelRatioF(); + + pdf::PDFCMSGeneric genericCms; + + for (pdf::PDFObjectReference reference : m_imageReferences) + { + std::optional pdfImage; + pdf::PDFObject imageObject = m_document->getObjectByReference(reference); + pdf::PDFRenderErrorReporterDummy errorReporter; + + if (!imageObject.isStream()) + { + // Image is not stream + continue; + } + + const pdf::PDFStream* stream = imageObject.getStream(); + try + { + pdf::PDFColorSpacePointer colorSpace; + const pdf::PDFDictionary* streamDictionary = stream->getDictionary(); + if (streamDictionary->hasKey("ColorSpace")) + { + const pdf::PDFObject& colorSpaceObject = m_document->getObject(streamDictionary->get("ColorSpace")); + if (colorSpaceObject.isName() || colorSpaceObject.isArray()) + { + pdf::PDFDictionary dummyDictionary; + colorSpace = pdf::PDFAbstractColorSpace::createColorSpace(&dummyDictionary, m_document, colorSpaceObject); + } + } + pdfImage.emplace(pdf::PDFImage::createImage(m_document, + stream, + colorSpace, + false, + pdf::RenderingIntent::Perceptual, + &errorReporter)); + } + catch (pdf::PDFException) + { + continue; + } + + QImage image = pdfImage->getImage(&genericCms, &errorReporter, nullptr); + + if (image.isNull()) + { + continue; + } + + QListWidgetItem* item = new QListWidgetItem(ui->imageListWidget); + QWidget* widget = new QWidget; + QHBoxLayout* layout = new QHBoxLayout(widget); + QCheckBox* checkbox = new QCheckBox(widget); + layout->addWidget(checkbox); + + image = image.scaled(imageSize.width(), imageSize.height(), Qt::KeepAspectRatio, Qt::FastTransformation); + item->setIcon(QIcon(QPixmap::fromImage(image))); + + ui->imageListWidget->setItemWidget(item, widget); + } +} + void PDFCreateBitonalDocumentDialog::updateUi() { ui->thresholdEditBox->setEnabled(ui->manualThresholdRadioButton->isChecked()); diff --git a/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.h b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.h index d45adee..1a3b37a 100644 --- a/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.h +++ b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.h @@ -18,7 +18,9 @@ #ifndef PDFCREATEBITONALDOCUMENTDIALOG_H #define PDFCREATEBITONALDOCUMENTDIALOG_H +#include "pdfcms.h" #include "pdfdocument.h" +#include "pdfobjectutils.h" #include #include @@ -36,7 +38,7 @@ class PDFCreateBitonalDocumentDialog : public QDialog Q_OBJECT public: - explicit PDFCreateBitonalDocumentDialog(const pdf::PDFDocument* document, QWidget* parent); + explicit PDFCreateBitonalDocumentDialog(const pdf::PDFDocument* document, const pdf::PDFCMS* cms, QWidget* parent); virtual ~PDFCreateBitonalDocumentDialog() override; pdf::PDFDocument takeBitonaldDocument() { return qMove(m_bitonalDocument); } @@ -44,16 +46,21 @@ public: private: void createBitonalDocument(); void onCreateBitonalDocumentButtonClicked(); + void loadImages(); void updateUi(); Ui::PDFCreateBitonalDocumentDialog* ui; const pdf::PDFDocument* m_document; + const pdf::PDFCMS* m_cms; QPushButton* m_createBitonalDocumentButton; bool m_conversionInProgress; bool m_processed; QFuture m_future; pdf::PDFDocument m_bitonalDocument; + pdf::PDFObjectClassifier m_classifier; + std::vector m_imageReferences; + std::vector m_imagesToBeConvertedReferences; }; } // namespace pdfviewer diff --git a/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.ui b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.ui index d877c0d..e9869c7 100644 --- a/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.ui +++ b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.ui @@ -13,16 +13,7 @@ Create Bitonal Document - - - - - - 1 - - - - + @@ -151,6 +142,16 @@ + + + + QListView::Adjust + + + QListView::IconMode + + + diff --git a/Pdf4QtViewer/pdfprogramcontroller.cpp b/Pdf4QtViewer/pdfprogramcontroller.cpp index 3feec4a..0a3ea9b 100644 --- a/Pdf4QtViewer/pdfprogramcontroller.cpp +++ b/Pdf4QtViewer/pdfprogramcontroller.cpp @@ -1256,7 +1256,8 @@ void PDFProgramController::onActionSanitizeTriggered() void PDFProgramController::onActionCreateBitonalDocumentTriggered() { - PDFCreateBitonalDocumentDialog dialog(m_pdfDocument.data(), m_mainWindow); + auto cms = m_CMSManager->getCurrentCMS(); + PDFCreateBitonalDocumentDialog dialog(m_pdfDocument.data(), cms.data(), m_mainWindow); if (dialog.exec() == QDialog::Accepted) {