mirror of https://github.com/JakubMelka/PDF4QT.git
Render tool basics
This commit is contained in:
parent
584a992da6
commit
428e5dc2ad
|
@ -681,11 +681,13 @@ void PDFPageImageExportSettings::setPixelResolution(int pixelResolution)
|
|||
m_pixelResolution = pixelResolution;
|
||||
}
|
||||
|
||||
bool PDFPageImageExportSettings::validate(QString* errorMessagePtr)
|
||||
bool PDFPageImageExportSettings::validate(QString* errorMessagePtr, bool validatePageSelection, bool validateFileSettings, bool validateResolution) const
|
||||
{
|
||||
QString dummy;
|
||||
QString& errorMessage = errorMessagePtr ? *errorMessagePtr : dummy;
|
||||
|
||||
if (validateFileSettings)
|
||||
{
|
||||
if (m_directory.isEmpty())
|
||||
{
|
||||
errorMessage = PDFTranslationContext::tr("Target directory is empty.");
|
||||
|
@ -711,8 +713,11 @@ bool PDFPageImageExportSettings::validate(QString* errorMessagePtr)
|
|||
errorMessage = PDFTranslationContext::tr("File template must contain character '%' for page number.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check page selection
|
||||
if (validatePageSelection)
|
||||
{
|
||||
if (m_pageSelectionMode == PageSelectionMode::Selection)
|
||||
{
|
||||
std::vector<PDFInteger> pages = getPages();
|
||||
|
@ -728,7 +733,10 @@ bool PDFPageImageExportSettings::validate(QString* errorMessagePtr)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (validateResolution)
|
||||
{
|
||||
if (m_resolutionMode == ResolutionMode::DPI && (m_dpiResolution < getMinDPIResolution() || m_dpiResolution > getMaxDPIResolution()))
|
||||
{
|
||||
errorMessage = PDFTranslationContext::tr("DPI resolution should be in range %1 to %2.").arg(getMinDPIResolution()).arg(getMaxDPIResolution());
|
||||
|
@ -740,6 +748,7 @@ bool PDFPageImageExportSettings::validate(QString* errorMessagePtr)
|
|||
errorMessage = PDFTranslationContext::tr("Pixel resolution should be in range %1 to %2.").arg(getMinPixelResolution()).arg(getMaxPixelResolution());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -338,7 +338,7 @@ public:
|
|||
void setPixelResolution(int pixelResolution);
|
||||
|
||||
/// Validates the settings, if they can be used for image generation
|
||||
bool validate(QString* errorMessagePtr);
|
||||
bool validate(QString* errorMessagePtr, bool validatePageSelection = true, bool validateFileSettings = true, bool validateResolution = true) const;
|
||||
|
||||
/// Returns list of selected pages
|
||||
std::vector<PDFInteger> getPages() const;
|
||||
|
|
|
@ -278,6 +278,15 @@ void PDFToolAbstractApplication::initializeCommandLineParser(QCommandLineParser*
|
|||
parser->addOption(QCommandLineOption("cms-profile-cmyk", "CMYK color profile for CMYK device.", "profile"));
|
||||
parser->addOption(QCommandLineOption("cms-profile-dir", "External directory containing color profiles.", "directory"));
|
||||
}
|
||||
|
||||
if (optionFlags.testFlag(RenderFlags))
|
||||
{
|
||||
const pdf::PDFRenderer::Features defaultFeatures = pdf::PDFRenderer::getDefaultFeatures();
|
||||
for (const PDFToolOptions::RenderFeatureInfo& info : PDFToolOptions::getRenderFeatures())
|
||||
{
|
||||
parser->addOption(QCommandLineOption(info.option, info.description, "bool", defaultFeatures.testFlag(info.feature) ? "1" : "0"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PDFToolOptions PDFToolAbstractApplication::getOptions(QCommandLineParser* parser) const
|
||||
|
@ -729,6 +738,26 @@ PDFToolOptions PDFToolAbstractApplication::getOptions(QCommandLineParser* parser
|
|||
setProfile("cms-profile-dir", options.cmsSettings.profileDirectory);
|
||||
}
|
||||
|
||||
if (optionFlags.testFlag(RenderFlags))
|
||||
{
|
||||
for (const PDFToolOptions::RenderFeatureInfo& info : PDFToolOptions::getRenderFeatures())
|
||||
{
|
||||
QString textValue = parser->value(info.option);
|
||||
|
||||
bool ok = false;
|
||||
bool value = textValue.toInt(&ok);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
options.renderFeatures.setFlag(info.feature, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
PDFConsole::writeError(PDFToolTranslationContext::tr("Uknown bool value '%1'. Default value is used.").arg(textValue), options.outputCodec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
@ -865,4 +894,17 @@ std::vector<pdf::PDFInteger> PDFToolOptions::getPageRange(pdf::PDFInteger pageCo
|
|||
return pageIndices;
|
||||
}
|
||||
|
||||
std::vector<PDFToolOptions::RenderFeatureInfo> PDFToolOptions::getRenderFeatures()
|
||||
{
|
||||
return {
|
||||
RenderFeatureInfo{ "render-antialiasing", "Antialiasing for lines, shapes, etc.", pdf::PDFRenderer::Antialiasing },
|
||||
RenderFeatureInfo{ "render-text-antialiasing", "Antialiasing for text outlines.", pdf::PDFRenderer::TextAntialiasing },
|
||||
RenderFeatureInfo{ "render-smooth-img", "Smooth image transformation (slower, but better quality images).", pdf::PDFRenderer::SmoothImages },
|
||||
RenderFeatureInfo{ "render-ignore-opt-content", "Ignore optional content settings (draw everything).", pdf::PDFRenderer::IgnoreOptionalContent },
|
||||
RenderFeatureInfo{ "render-clip-to-crop-box", "Clip page graphics to crop box.", pdf::PDFRenderer::ClipToCropBox },
|
||||
RenderFeatureInfo{ "render-invert-colors", "Invert all colors.", pdf::PDFRenderer::InvertColors },
|
||||
RenderFeatureInfo{ "render-display-annot", "Display annotations.", pdf::PDFRenderer::DisplayAnnotations }
|
||||
};
|
||||
}
|
||||
|
||||
} // pdftool
|
||||
|
|
|
@ -122,11 +122,24 @@ struct PDFToolOptions
|
|||
// For option 'ColorManagementSystem'
|
||||
pdf::PDFCMSSettings cmsSettings;
|
||||
|
||||
// For option 'RenderFlags'
|
||||
pdf::PDFRenderer::Features renderFeatures = pdf::PDFRenderer::getDefaultFeatures();
|
||||
|
||||
/// Returns page range. If page range is invalid, then \p errorMessage is empty.
|
||||
/// \param pageCount Page count
|
||||
/// \param[out] errorMessage Error message
|
||||
/// \param zeroBased Convert to zero based page range?
|
||||
std::vector<pdf::PDFInteger> getPageRange(pdf::PDFInteger pageCount, QString& errorMessage, bool zeroBased) const;
|
||||
|
||||
struct RenderFeatureInfo
|
||||
{
|
||||
QString option;
|
||||
QString description;
|
||||
pdf::PDFRenderer::Feature feature;
|
||||
};
|
||||
|
||||
/// Returns a list of available renderer features
|
||||
static std::vector<RenderFeatureInfo> getRenderFeatures();
|
||||
};
|
||||
|
||||
/// Base class for all applications
|
||||
|
|
|
@ -20,5 +20,145 @@
|
|||
namespace pdftool
|
||||
{
|
||||
|
||||
static PDFToolRender s_toolRenderApplication;
|
||||
static PDFToolBenchmark s_toolBenchmarkApplication;
|
||||
|
||||
QString PDFToolRender::getStandardString(PDFToolAbstractApplication::StandardString standardString) const
|
||||
{
|
||||
switch (standardString)
|
||||
{
|
||||
case Command:
|
||||
return "render";
|
||||
|
||||
case Name:
|
||||
return PDFToolTranslationContext::tr("Render document");
|
||||
|
||||
case Description:
|
||||
return PDFToolTranslationContext::tr("Render selected pages of document into image files.");
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
PDFToolAbstractApplication::Options PDFToolRender::getOptionsFlags() const
|
||||
{
|
||||
return ConsoleFormat | OpenDocument | PageSelector | ImageWriterSettings | ImageExportSettingsFiles | ImageExportSettingsResolution | ColorManagementSystem | RenderFlags;
|
||||
}
|
||||
|
||||
QString PDFToolBenchmark::getStandardString(PDFToolAbstractApplication::StandardString standardString) const
|
||||
{
|
||||
switch (standardString)
|
||||
{
|
||||
case Command:
|
||||
return "benchmark";
|
||||
|
||||
case Name:
|
||||
return PDFToolTranslationContext::tr("Benchmark rendering");
|
||||
|
||||
case Description:
|
||||
return PDFToolTranslationContext::tr("Benchmark page rendering (measure time, detect errors).");
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
PDFToolAbstractApplication::Options PDFToolBenchmark::getOptionsFlags() const
|
||||
{
|
||||
return ConsoleFormat | OpenDocument | PageSelector | ImageExportSettingsResolution | ColorManagementSystem | RenderFlags;
|
||||
}
|
||||
|
||||
int PDFToolRenderBase::execute(const PDFToolOptions& options)
|
||||
{
|
||||
pdf::PDFDocument document;
|
||||
QByteArray sourceData;
|
||||
if (!readDocument(options, document, &sourceData))
|
||||
{
|
||||
return ErrorDocumentReading;
|
||||
}
|
||||
|
||||
QString parseError;
|
||||
std::vector<pdf::PDFInteger> pages = options.getPageRange(document.getCatalog()->getPageCount(), parseError, true);
|
||||
|
||||
if (!parseError.isEmpty())
|
||||
{
|
||||
PDFConsole::writeError(parseError, options.outputCodec);
|
||||
return ErrorInvalidArguments;
|
||||
}
|
||||
|
||||
QString errorMessage;
|
||||
Options optionFlags = getOptionsFlags();
|
||||
if (!options.imageExportSettings.validate(&errorMessage, false, optionFlags.testFlag(ImageExportSettingsFiles), optionFlags.testFlag(ImageExportSettingsResolution)))
|
||||
{
|
||||
PDFConsole::writeError(errorMessage, options.outputCodec);
|
||||
return ErrorInvalidArguments;
|
||||
}
|
||||
|
||||
// We are ready to render the document
|
||||
pdf::PDFOptionalContentActivity optionalContentActivity(&document, pdf::OCUsage::Export, nullptr);
|
||||
m_cms = m_proxy->getCMSManager()->getCurrentCMS();
|
||||
pdf::PDFRasterizerPool rasterizerPool(&document, m_proxy->getFontCache(), m_proxy->getCMSManager(),
|
||||
&optionalContentActivity, m_proxy->getFeatures(), m_proxy->getMeshQualitySettings(),
|
||||
pdf::PDFRasterizerPool::getDefaultRasterizerCount(), m_proxy->isUsingOpenGL(), m_proxy->getSurfaceFormat(), this);
|
||||
connect(&rasterizerPool, &pdf::PDFRasterizerPool::renderError, this, &PDFRenderToImagesDialog::onRenderError);
|
||||
|
||||
auto imageSizeGetter = [&options](const pdf::PDFPage* page) -> QSize
|
||||
{
|
||||
Q_ASSERT(page);
|
||||
|
||||
switch (options.imageExportSettings.getResolutionMode())
|
||||
{
|
||||
case pdf::PDFPageImageExportSettings::ResolutionMode::DPI:
|
||||
{
|
||||
QSizeF size = page->getRotatedMediaBox().size() * pdf::PDF_POINT_TO_INCH * options.imageExportSettings.getDpiResolution();
|
||||
return size.toSize();
|
||||
}
|
||||
|
||||
case pdf::PDFPageImageExportSettings::ResolutionMode::Pixels:
|
||||
{
|
||||
int pixelResolution = options.imageExportSettings.getPixelResolution();
|
||||
QSizeF size = page->getRotatedMediaBox().size().scaled(pixelResolution, pixelResolution, Qt::KeepAspectRatio);
|
||||
return size.toSize();
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QSize();
|
||||
};
|
||||
|
||||
auto processImage = [this](const pdf::PDFInteger pageIndex, QImage&& image)
|
||||
{
|
||||
QString fileName = m_imageExportSettings.getOutputFileName(pageIndex, m_imageWriterSettings.getCurrentFormat());
|
||||
|
||||
QImageWriter imageWriter(fileName, m_imageWriterSettings.getCurrentFormat());
|
||||
imageWriter.setSubType(m_imageWriterSettings.getCurrentSubtype());
|
||||
imageWriter.setCompression(m_imageWriterSettings.getCompression());
|
||||
imageWriter.setQuality(m_imageWriterSettings.getQuality());
|
||||
imageWriter.setGamma(m_imageWriterSettings.getGamma());
|
||||
imageWriter.setOptimizedWrite(m_imageWriterSettings.hasOptimizedWrite());
|
||||
imageWriter.setProgressiveScanWrite(m_imageWriterSettings.hasProgressiveScanWrite());
|
||||
|
||||
if (!imageWriter.write(image))
|
||||
{
|
||||
emit m_rasterizerPool->renderError(pdf::PDFRenderError(pdf::RenderErrorType::Error, tr("Can't write page image to file '%1', because: %2.").arg(fileName).arg(imageWriter.errorString())));
|
||||
}
|
||||
};
|
||||
|
||||
rasterizerPool.render(pageIndices, imageSizeGetter, processImage, m_progress);
|
||||
|
||||
return ExitSuccess;
|
||||
}
|
||||
|
||||
} // namespace pdftool
|
||||
|
|
|
@ -36,6 +36,13 @@ public:
|
|||
virtual Options getOptionsFlags() const override;
|
||||
};
|
||||
|
||||
class PDFToolBenchmark : public PDFToolRenderBase
|
||||
{
|
||||
public:
|
||||
virtual QString getStandardString(StandardString standardString) const override;
|
||||
virtual Options getOptionsFlags() const override;
|
||||
};
|
||||
|
||||
} // namespace pdftool
|
||||
|
||||
#endif // PDFTOOLRENDER_H
|
||||
|
|
Loading…
Reference in New Issue