Settings for rendering

This commit is contained in:
Jakub Melka 2020-10-25 18:55:25 +01:00
parent 59c09c9095
commit 584a992da6
6 changed files with 412 additions and 13 deletions

View File

@ -301,6 +301,7 @@ private:
class PDFFORQTLIBSHARED_EXPORT PDFPageImageExportSettings
{
public:
explicit PDFPageImageExportSettings() : PDFPageImageExportSettings(nullptr) { }
explicit PDFPageImageExportSettings(const PDFDocument* document);
enum class PageSelectionMode

View File

@ -53,6 +53,7 @@ SOURCES += \
pdftoolinfonameddestinations.cpp \
pdftoolinfopageboxes.cpp \
pdftoolinfostructuretree.cpp \
pdftoolrender.cpp \
pdftoolverifysignatures.cpp \
pdftoolxml.cpp
@ -79,5 +80,6 @@ HEADERS += \
pdftoolinfonameddestinations.h \
pdftoolinfopageboxes.h \
pdftoolinfostructuretree.h \
pdftoolrender.h \
pdftoolverifysignatures.h \
pdftoolxml.h

View File

@ -241,6 +241,43 @@ void PDFToolAbstractApplication::initializeCommandLineParser(QCommandLineParser*
{
parser->addOption(QCommandLineOption("character-maps", "Show character maps for embedded fonts."));
}
if (optionFlags.testFlag(ImageWriterSettings))
{
parser->addOption(QCommandLineOption("image-format", "Image format. Common formats as png, jpeg, are supported.", "format", "png"));
parser->addOption(QCommandLineOption("image-subtype", "Image format subtype. Some image formats can have this setting.", "subtype"));
parser->addOption(QCommandLineOption("image-compress-lvl", "Image compression level. Different formats can have different meaning.", "level", "9"));
parser->addOption(QCommandLineOption("image-quality", "Image quality. Different formats can have different meaning.", "quality", "100"));
parser->addOption(QCommandLineOption("image-optimized-write", "Use optimized write mode."));
parser->addOption(QCommandLineOption("image-progressive-scan-write", "Use image progressive scan mode."));
}
if (optionFlags.testFlag(ImageExportSettingsFiles))
{
parser->addOption(QCommandLineOption("image-output-dir", "Output directory, where images are saved.", "dir"));
parser->addOption(QCommandLineOption("image-template-fn", "Template file name, must contain '%' character, must not contain suffix.", "template file name", "Image_%"));
}
if (optionFlags.testFlag(ImageExportSettingsResolution))
{
parser->addOption(QCommandLineOption("image-res-mode", "Image resolution mode (valid values are dpi|pixel). Dpi is default.", "mode", "dpi"));
parser->addOption(QCommandLineOption("image-res-dpi", "DPI resolution of target image.", "dpi"));
parser->addOption(QCommandLineOption("image-res-pixel", "Pixel resolution of target image.", "pixel"));
}
if (optionFlags.testFlag(ColorManagementSystem))
{
parser->addOption(QCommandLineOption("cms", "Color management system. Valid values are generic|lcms.", "cms", "lcms"));
parser->addOption(QCommandLineOption("cms-accuracy", "Accuracy of cms system. Valid values are low|medium|high. Higher accuracy means higher memory consumption.", "accuracy", "medium"));
parser->addOption(QCommandLineOption("cms-intent", "Rendering intent. Valid values are auto|perceptual|abs|rel|saturation.", "intent", "auto"));
parser->addOption(QCommandLineOption("cms-black-compensated", "Black point compensation.", "bool", "1"));
parser->addOption(QCommandLineOption("cms-white-paper-trans", "Transform also color of paper using cms.", "bool", "0"));
parser->addOption(QCommandLineOption("cms-profile-output", "Output color profile.", "profile"));
parser->addOption(QCommandLineOption("cms-profile-gray", "Gray color profile for gray device.", "profile"));
parser->addOption(QCommandLineOption("cms-profile-rgb", "RGB color profile for RGB device.", "profile"));
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"));
}
}
PDFToolOptions PDFToolAbstractApplication::getOptions(QCommandLineParser* parser) const
@ -414,6 +451,284 @@ PDFToolOptions PDFToolAbstractApplication::getOptions(QCommandLineParser* parser
options.showCharacterMapsForEmbeddedFonts = parser->isSet("character-maps");
}
if (optionFlags.testFlag(ImageWriterSettings))
{
// Image format
QByteArray imageWriterFormat = parser->value("image-format").toLatin1();
if (!options.imageWriterSettings.getFormats().contains(imageWriterFormat))
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Image format '%1' is not supported. Defaulting to png.").arg(QString::fromLatin1(imageWriterFormat)), options.outputCodec);
imageWriterFormat = "png";
}
Q_ASSERT(options.imageWriterSettings.getFormats().contains(imageWriterFormat));
options.imageWriterSettings.selectFormat(imageWriterFormat);
// Image subtype
if (parser->isSet("image-subtype"))
{
QByteArray imageWriterSubtype = parser->value("image-subtype").toLatin1();
if (options.imageWriterSettings.getSubtypes().contains(imageWriterSubtype))
{
options.imageWriterSettings.setCurrentSubtype(imageWriterSubtype);
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Image format subtype '%1' is not supported.").arg(QString::fromLatin1(imageWriterSubtype)), options.outputCodec);
}
}
// Compression level
if (parser->isSet("image-compress-lvl"))
{
QString valueText = parser->value("image-compress-lvl");
bool ok = false;
int value = valueText.toInt(&ok);
if (ok)
{
if (options.imageWriterSettings.isOptionSupported(QImageIOHandler::CompressionRatio))
{
options.imageWriterSettings.setCompression(value);
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Image compression for current format is not supported."), options.outputCodec);
}
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Invalid compression level '%1'.").arg(valueText), options.outputCodec);
}
}
// Quality
if (parser->isSet("image-quality"))
{
QString valueText = parser->value("image-quality");
bool ok = false;
int value = valueText.toInt(&ok);
if (ok)
{
if (options.imageWriterSettings.isOptionSupported(QImageIOHandler::Quality))
{
options.imageWriterSettings.setQuality(value);
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Image quality settings for current format is not supported."), options.outputCodec);
}
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Invalid image quality '%1'.").arg(valueText), options.outputCodec);
}
}
options.imageWriterSettings.setOptimizedWrite(false);
options.imageWriterSettings.setProgressiveScanWrite(false);
if (parser->isSet("image-optimized-write"))
{
if (options.imageWriterSettings.isOptionSupported(QImageIOHandler::OptimizedWrite))
{
options.imageWriterSettings.setOptimizedWrite(true);
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Optimized write is not supported."), options.outputCodec);
}
}
if (parser->isSet("image-progressive-scan-write"))
{
if (options.imageWriterSettings.isOptionSupported(QImageIOHandler::ProgressiveScanWrite))
{
options.imageWriterSettings.setProgressiveScanWrite(true);
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Progressive scan write is not supported."), options.outputCodec);
}
}
}
if (optionFlags.testFlag(ImageExportSettingsFiles))
{
QFileInfo documentFileInfo(options.document);
QString outputDir = documentFileInfo.path();
if (parser->isSet("image-output-dir"))
{
outputDir = parser->value("image-output-dir");
}
options.imageExportSettings.setDirectory(outputDir);
options.imageExportSettings.setFileTemplate(parser->value("image-template-fn"));
}
if (optionFlags.testFlag(ImageExportSettingsResolution))
{
QString resMode = parser->value("image-res-mode").toLower();
if (resMode == "dpi")
{
options.imageExportSettings.setResolutionMode(pdf::PDFPageImageExportSettings::ResolutionMode::DPI);
}
else if (resMode == "pixel")
{
options.imageExportSettings.setResolutionMode(pdf::PDFPageImageExportSettings::ResolutionMode::Pixels);
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Invalid image resolution mode '%1'. Defaulting to dpi.").arg(resMode), options.outputCodec);
options.imageExportSettings.setResolutionMode(pdf::PDFPageImageExportSettings::ResolutionMode::DPI);
}
if (parser->isSet("image-res-dpi"))
{
if (options.imageExportSettings.getResolutionMode() != pdf::PDFPageImageExportSettings::ResolutionMode::DPI)
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Cannot set dpi value, resolution mode must be dpi."), options.outputCodec);
}
bool ok = false;
int dpi = parser->value("image-res-dpi").toInt(&ok);
if (ok)
{
int boundedDpi = qBound(pdf::PDFPageImageExportSettings::getMinDPIResolution(), dpi, pdf::PDFPageImageExportSettings::getMaxDPIResolution());
if (boundedDpi != dpi)
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Dpi must be in range from %1 to %2. Defaulting to %3.").arg(pdf::PDFPageImageExportSettings::getMinDPIResolution()).arg(pdf::PDFPageImageExportSettings::getMaxDPIResolution()).arg(boundedDpi), options.outputCodec);
}
options.imageExportSettings.setDpiResolution(dpi);
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Invalid image dpi value '%1'.").arg(parser->value("image-res-dpi")), options.outputCodec);
}
}
if (parser->isSet("image-res-pixel"))
{
if (options.imageExportSettings.getResolutionMode() != pdf::PDFPageImageExportSettings::ResolutionMode::Pixels)
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Cannot set pixel value, resolution mode must be pixel."), options.outputCodec);
}
bool ok = false;
int pixel = parser->value("image-res-pixel").toInt(&ok);
if (ok)
{
int boundedPixel = qBound(pdf::PDFPageImageExportSettings::getMinPixelResolution(), pixel, pdf::PDFPageImageExportSettings::getMaxPixelResolution());
if (boundedPixel != pixel)
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Pixel value must be in range from %1 to %2. Defaulting to %3.").arg(pdf::PDFPageImageExportSettings::getMinPixelResolution()).arg(pdf::PDFPageImageExportSettings::getMaxPixelResolution()).arg(boundedPixel), options.outputCodec);
}
options.imageExportSettings.setPixelResolution(pixel);
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Invalid image pixel value '%1'.").arg(parser->value("image-res-pixel")), options.outputCodec);
}
}
}
if (optionFlags.testFlag(ColorManagementSystem))
{
pdf::PDFCMSManager cmsManager(nullptr);
options.cmsSettings = cmsManager.getDefaultSettings();
QString cms = parser->value("cms");
if (cms == "generic")
{
options.cmsSettings.system = pdf::PDFCMSSettings::System::Generic;
}
else if (cms == "lcms")
{
options.cmsSettings.system = pdf::PDFCMSSettings::System::LittleCMS2;
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Unknown color management system '%1'. Defaulting to lcms.").arg(cms), options.outputCodec);
options.cmsSettings.system = pdf::PDFCMSSettings::System::LittleCMS2;
}
QString accuracy = parser->value("cms-accuracy");
if (accuracy == "medium")
{
options.cmsSettings.accuracy = pdf::PDFCMSSettings::Accuracy::Medium;
}
else if (accuracy == "low")
{
options.cmsSettings.accuracy = pdf::PDFCMSSettings::Accuracy::Low;
}
else if (accuracy == "high")
{
options.cmsSettings.accuracy = pdf::PDFCMSSettings::Accuracy::High;
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Uknown color management system accuracy '%1'. Defaulting to medium.").arg(accuracy), options.outputCodec);
options.cmsSettings.accuracy = pdf::PDFCMSSettings::Accuracy::Medium;
}
QString intent = parser->value("cms-intent");
if (intent == "auto")
{
options.cmsSettings.intent = pdf::RenderingIntent::Auto;
}
else if (intent == "perceptual")
{
options.cmsSettings.intent = pdf::RenderingIntent::Perceptual;
}
else if (intent == "abs")
{
options.cmsSettings.intent = pdf::RenderingIntent::AbsoluteColorimetric;
}
else if (intent == "rel")
{
options.cmsSettings.intent = pdf::RenderingIntent::RelativeColorimetric;
}
else if (intent == "saturation")
{
options.cmsSettings.intent = pdf::RenderingIntent::Saturation;
}
else
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Uknown color management system rendering intent '%1'. Defaulting to auto.").arg(intent), options.outputCodec);
options.cmsSettings.intent = pdf::RenderingIntent::Auto;
}
if (parser->isSet("cms-black-compensated"))
{
options.cmsSettings.isBlackPointCompensationActive = parser->value("cms-black-compensated").toInt();
}
if (parser->isSet("cms-white-paper-trans"))
{
options.cmsSettings.isWhitePaperColorTransformed = parser->value("cms-white-paper-trans").toInt();
}
auto setProfile = [&parser, &options](QString settings, QString& profile)
{
if (parser->isSet(settings))
{
profile = parser->value(settings);
}
};
setProfile("cms-profile-output", options.cmsSettings.outputCS);
setProfile("cms-profile-gray", options.cmsSettings.deviceGray);
setProfile("cms-profile-rgb", options.cmsSettings.deviceRGB);
setProfile("cms-profile-cmyk", options.cmsSettings.deviceCMYK);
setProfile("cms-profile-dir", options.cmsSettings.profileDirectory);
}
return options;
}

View File

@ -21,6 +21,8 @@
#include "pdfoutputformatter.h"
#include "pdfdocument.h"
#include "pdfdocumenttextflow.h"
#include "pdfrenderer.h"
#include "pdfcms.h"
#include <QtGlobal>
#include <QString>
@ -111,6 +113,15 @@ struct PDFToolOptions
// For option 'CharacterMaps'
bool showCharacterMapsForEmbeddedFonts = false;
// For option 'ImageWriterSettings'
pdf::PDFImageWriterSettings imageWriterSettings;
// For option 'ImageExportSettings'
pdf::PDFPageImageExportSettings imageExportSettings;
// For option 'ColorManagementSystem'
pdf::PDFCMSSettings cmsSettings;
/// Returns page range. If page range is invalid, then \p errorMessage is empty.
/// \param pageCount Page count
/// \param[out] errorMessage Error message
@ -148,19 +159,24 @@ public:
enum Option
{
ConsoleFormat = 0x0001, ///< Set format of console output (text, xml or html)
OpenDocument = 0x0002, ///< Flags for document reading
SignatureVerification = 0x0004, ///< Flags for signature verification,
XmlExport = 0x0008, ///< Flags for xml export
Attachments = 0x0010, ///< Flags for attachments manipulating
DateFormat = 0x0020, ///< Date format
ComputeHashes = 0x0040, ///< Compute hashes
PageSelector = 0x0080, ///< Select page range (or all pages)
TextAnalysis = 0x0100, ///< Text analysis options
TextShow = 0x0200, ///< Text extract and show options
VoiceSelector = 0x0400, ///< Select voice from SAPI
TextSpeech = 0x0800, ///< Text speech options
CharacterMaps = 0x1000, ///< Character maps for embedded fonts
ConsoleFormat = 0x00000001, ///< Set format of console output (text, xml or html)
OpenDocument = 0x00000002, ///< Flags for document reading
SignatureVerification = 0x00000004, ///< Flags for signature verification,
XmlExport = 0x00000008, ///< Flags for xml export
Attachments = 0x00000010, ///< Flags for attachments manipulating
DateFormat = 0x00000020, ///< Date format
ComputeHashes = 0x00000040, ///< Compute hashes
PageSelector = 0x00000080, ///< Select page range (or all pages)
TextAnalysis = 0x00000100, ///< Text analysis options
TextShow = 0x00000200, ///< Text extract and show options
VoiceSelector = 0x00000400, ///< Select voice from SAPI
TextSpeech = 0x00000800, ///< Text speech options
CharacterMaps = 0x00001000, ///< Character maps for embedded fonts
ImageWriterSettings = 0x00002000, ///< Settings for writing images (for example, format, etc.)
ImageExportSettingsFiles = 0x00004000, ///< Settings for exporting page images to files
ImageExportSettingsResolution = 0x00008000, ///< Settings for resolution of exported images
ColorManagementSystem = 0x00010000, ///< Color management system settings
RenderFlags = 0x00020000, ///< Render flags for page image rasterizer
};
Q_DECLARE_FLAGS(Options, Option)

24
PdfTool/pdftoolrender.cpp Normal file
View File

@ -0,0 +1,24 @@
// Copyright (C) 2020 Jakub Melka
//
// This file is part of PdfForQt.
//
// PdfForQt is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// PdfForQt is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
#include "pdftoolrender.h"
namespace pdftool
{
} // namespace pdftool

41
PdfTool/pdftoolrender.h Normal file
View File

@ -0,0 +1,41 @@
// Copyright (C) 2020 Jakub Melka
//
// This file is part of PdfForQt.
//
// PdfForQt is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// PdfForQt is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFTOOLRENDER_H
#define PDFTOOLRENDER_H
#include "pdftoolabstractapplication.h"
namespace pdftool
{
class PDFToolRenderBase : public PDFToolAbstractApplication
{
public:
virtual int execute(const PDFToolOptions& options) override;
};
class PDFToolRender : public PDFToolRenderBase
{
public:
virtual QString getStandardString(StandardString standardString) const override;
virtual Options getOptionsFlags() const override;
};
} // namespace pdftool
#endif // PDFTOOLRENDER_H