mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Issue #107: Conversion algorithm
This commit is contained in:
@ -24,6 +24,7 @@
|
||||
#include "pdfdbgheap.h"
|
||||
#include "pdfexception.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "pdfimageconversion.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
@ -39,6 +40,64 @@
|
||||
namespace pdfviewer
|
||||
{
|
||||
|
||||
PDFCreateBitonalDocumentPreviewWidget::PDFCreateBitonalDocumentPreviewWidget(QWidget* parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PDFCreateBitonalDocumentPreviewWidget::~PDFCreateBitonalDocumentPreviewWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PDFCreateBitonalDocumentPreviewWidget::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
QPainter painter(this);
|
||||
painter.fillRect(rect(), Qt::white);
|
||||
|
||||
// Caption rect
|
||||
QRect captionRect = rect();
|
||||
captionRect.setHeight(painter.fontMetrics().lineSpacing() * 2);
|
||||
|
||||
painter.fillRect(captionRect, QColor::fromRgb(0, 0, 128, 255));
|
||||
|
||||
if (!m_caption.isEmpty())
|
||||
{
|
||||
painter.setPen(Qt::white);
|
||||
painter.drawText(captionRect, m_caption, QTextOption(Qt::AlignCenter));
|
||||
}
|
||||
|
||||
QRect imageRect = rect();
|
||||
imageRect.setTop(captionRect.bottom());
|
||||
imageRect = imageRect.adjusted(16, 16, -32, -32);
|
||||
|
||||
if (imageRect.isValid() && !m_image.isNull())
|
||||
{
|
||||
QRect imageDrawRect = imageRect;
|
||||
imageDrawRect.setSize(m_image.size().scaled(imageRect.size(), Qt::KeepAspectRatio));
|
||||
imageDrawRect.moveCenter(imageRect.center());
|
||||
painter.drawImage(imageDrawRect, m_image);
|
||||
}
|
||||
}
|
||||
|
||||
void PDFCreateBitonalDocumentPreviewWidget::setCaption(QString caption)
|
||||
{
|
||||
if (m_caption != caption)
|
||||
{
|
||||
m_caption = caption;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFCreateBitonalDocumentPreviewWidget::setImage(QImage image)
|
||||
{
|
||||
m_image = std::move(image);
|
||||
update();
|
||||
}
|
||||
|
||||
class ImagePreviewDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
@ -148,10 +207,18 @@ PDFCreateBitonalDocumentDialog::PDFCreateBitonalDocumentDialog(const pdf::PDFDoc
|
||||
m_cms(cms),
|
||||
m_createBitonalDocumentButton(nullptr),
|
||||
m_conversionInProgress(false),
|
||||
m_processed(false)
|
||||
m_processed(false),
|
||||
m_leftPreviewWidget(new PDFCreateBitonalDocumentPreviewWidget(this)),
|
||||
m_rightPreviewWidget(new PDFCreateBitonalDocumentPreviewWidget(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_leftPreviewWidget->setCaption(tr("ORIGINAL"));
|
||||
m_rightPreviewWidget->setCaption(tr("BITONIC"));
|
||||
|
||||
ui->mainGridLayout->addWidget(m_leftPreviewWidget, 1, 1);
|
||||
ui->mainGridLayout->addWidget(m_rightPreviewWidget, 1, 2);
|
||||
|
||||
m_classifier.classify(document);
|
||||
m_imageReferences = m_classifier.getObjectsByType(pdf::PDFObjectClassifier::Image);
|
||||
|
||||
@ -159,6 +226,10 @@ PDFCreateBitonalDocumentDialog::PDFCreateBitonalDocumentDialog(const pdf::PDFDoc
|
||||
connect(m_createBitonalDocumentButton, &QPushButton::clicked, this, &PDFCreateBitonalDocumentDialog::onCreateBitonalDocumentButtonClicked);
|
||||
connect(ui->automaticThresholdRadioButton, &QRadioButton::clicked, this, &PDFCreateBitonalDocumentDialog::updateUi);
|
||||
connect(ui->manualThresholdRadioButton, &QRadioButton::clicked, this, &PDFCreateBitonalDocumentDialog::updateUi);
|
||||
connect(ui->automaticThresholdRadioButton, &QRadioButton::clicked, this, &PDFCreateBitonalDocumentDialog::updatePreview);
|
||||
connect(ui->manualThresholdRadioButton, &QRadioButton::clicked, this, &PDFCreateBitonalDocumentDialog::updatePreview);
|
||||
connect(ui->imageListWidget, &QListWidget::currentItemChanged, this, &PDFCreateBitonalDocumentDialog::updatePreview);
|
||||
connect(ui->thresholdEditBox, &QSpinBox::editingFinished, this, &PDFCreateBitonalDocumentDialog::updatePreview);
|
||||
|
||||
pdf::PDFWidgetUtils::scaleWidget(this, QSize(640, 380));
|
||||
updateUi();
|
||||
@ -167,6 +238,7 @@ PDFCreateBitonalDocumentDialog::PDFCreateBitonalDocumentDialog(const pdf::PDFDoc
|
||||
ui->imageListWidget->setItemDelegate( new ImagePreviewDelegate(&m_imagesToBeConverted, this));
|
||||
|
||||
loadImages();
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
PDFCreateBitonalDocumentDialog::~PDFCreateBitonalDocumentDialog()
|
||||
@ -243,6 +315,40 @@ void PDFCreateBitonalDocumentDialog::updateUi()
|
||||
m_createBitonalDocumentButton->setEnabled(!m_conversionInProgress);
|
||||
}
|
||||
|
||||
void PDFCreateBitonalDocumentDialog::updatePreview()
|
||||
{
|
||||
QModelIndex index = ui->imageListWidget->currentIndex();
|
||||
|
||||
m_previewImageLeft = QImage();
|
||||
m_previewImageRight = QImage();
|
||||
|
||||
if (index.isValid())
|
||||
{
|
||||
const ImageConversionInfo& info = m_imagesToBeConverted.at(index.row());
|
||||
|
||||
std::optional<pdf::PDFImage> pdfImage = getImageFromReference(info.imageReference);
|
||||
Q_ASSERT(pdfImage);
|
||||
|
||||
pdf::PDFCMSGeneric cmsGeneric;
|
||||
pdf::PDFRenderErrorReporterDummy reporter;
|
||||
QImage image = pdfImage->getImage(&cmsGeneric, &reporter, nullptr);
|
||||
|
||||
pdf::PDFImageConversion imageConversion;
|
||||
imageConversion.setConversionMethod(ui->automaticThresholdRadioButton->isChecked() ? pdf::PDFImageConversion::ConversionMethod::Automatic : pdf::PDFImageConversion::ConversionMethod::Manual);
|
||||
imageConversion.setThreshold(ui->thresholdEditBox->value());
|
||||
imageConversion.setImage(image);
|
||||
|
||||
if (imageConversion.convert())
|
||||
{
|
||||
m_previewImageLeft = image;
|
||||
m_previewImageRight = imageConversion.getConvertedImage();
|
||||
}
|
||||
}
|
||||
|
||||
m_leftPreviewWidget->setImage(m_previewImageLeft);
|
||||
m_rightPreviewWidget->setImage(m_previewImageRight);
|
||||
}
|
||||
|
||||
std::optional<pdf::PDFImage> PDFCreateBitonalDocumentDialog::getImageFromReference(pdf::PDFObjectReference reference) const
|
||||
{
|
||||
std::optional<pdf::PDFImage> pdfImage;
|
||||
@ -285,3 +391,5 @@ std::optional<pdf::PDFImage> PDFCreateBitonalDocumentDialog::getImageFromReferen
|
||||
}
|
||||
|
||||
} // namespace pdfviewer
|
||||
|
||||
|
||||
|
@ -34,6 +34,24 @@ class PDFCreateBitonalDocumentDialog;
|
||||
namespace pdfviewer
|
||||
{
|
||||
|
||||
class PDFCreateBitonalDocumentPreviewWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PDFCreateBitonalDocumentPreviewWidget(QWidget* parent);
|
||||
virtual ~PDFCreateBitonalDocumentPreviewWidget() override;
|
||||
|
||||
virtual void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
void setCaption(QString caption);
|
||||
void setImage(QImage image);
|
||||
|
||||
private:
|
||||
QString m_caption;
|
||||
QImage m_image;
|
||||
};
|
||||
|
||||
class PDFCreateBitonalDocumentDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -56,6 +74,7 @@ private:
|
||||
void loadImages();
|
||||
|
||||
void updateUi();
|
||||
void updatePreview();
|
||||
|
||||
std::optional<pdf::PDFImage> getImageFromReference(pdf::PDFObjectReference reference) const;
|
||||
|
||||
@ -70,6 +89,12 @@ private:
|
||||
pdf::PDFObjectClassifier m_classifier;
|
||||
std::vector<pdf::PDFObjectReference> m_imageReferences;
|
||||
std::vector<ImageConversionInfo> m_imagesToBeConverted;
|
||||
|
||||
QImage m_previewImageLeft;
|
||||
QImage m_previewImageRight;
|
||||
|
||||
PDFCreateBitonalDocumentPreviewWidget* m_leftPreviewWidget;
|
||||
PDFCreateBitonalDocumentPreviewWidget* m_rightPreviewWidget;
|
||||
};
|
||||
|
||||
} // namespace pdfviewer
|
||||
|
@ -13,13 +13,23 @@
|
||||
<property name="windowTitle">
|
||||
<string>Create Bitonal Document</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,0,1,0" columnstretch="2,1,1">
|
||||
<layout class="QGridLayout" name="mainGridLayout" rowstretch="0,1,0" columnstretch="2,1,1">
|
||||
<item row="2" column="0" colspan="3">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QGroupBox" name="createBitonalSettingsGroupBox">
|
||||
<property name="title">
|
||||
<string>Color to Bitonal Conversion Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<layout class="QGridLayout" name="optionsGridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="automaticThresholdRadioButton">
|
||||
<property name="text">
|
||||
@ -50,99 +60,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" rowspan="2">
|
||||
<widget class="QLabel" name="originalImageLabel">
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="Window">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="Window">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>240</red>
|
||||
<green>240</green>
|
||||
<blue>240</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="Window">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" rowspan="2">
|
||||
<widget class="QLabel" name="convertedImageLabel">
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="Window">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="Window">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>240</red>
|
||||
<green>240</green>
|
||||
<blue>240</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="Window">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="3">
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QListWidget" name="imageListWidget">
|
||||
<property name="resizeMode">
|
||||
<enum>QListView::Adjust</enum>
|
||||
|
Reference in New Issue
Block a user