File indexing completed on 2025-01-19 03:51:00

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2007-08-02
0007  * Description : JPEG image export settings widget.
0008  *
0009  * SPDX-FileCopyrightText: 2007-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "dimgjpegexportsettings.h"
0016 
0017 // Qt includes
0018 
0019 #include <QApplication>
0020 #include <QFrame>
0021 #include <QGridLayout>
0022 #include <QLabel>
0023 #include <QLayout>
0024 #include <QString>
0025 #include <QComboBox>
0026 #include <QStyle>
0027 
0028 // KDE includes
0029 
0030 #include <klocalizedstring.h>
0031 
0032 // Local includes
0033 
0034 #include "dnuminput.h"
0035 
0036 namespace Digikam
0037 {
0038 
0039 class Q_DECL_HIDDEN DImgJPEGExportSettings::Private
0040 {
0041 
0042 public:
0043 
0044     explicit Private()
0045       : JPEGGrid            (nullptr),
0046         labelJPEGcompression(nullptr),
0047         labelWarning        (nullptr),
0048         labelSubSampling    (nullptr),
0049         subSamplingCB       (nullptr),
0050         JPEGcompression     (nullptr)
0051     {
0052     }
0053 
0054     QGridLayout*  JPEGGrid;
0055 
0056     QLabel*       labelJPEGcompression;
0057     QLabel*       labelWarning;
0058     QLabel*       labelSubSampling;
0059 
0060     QComboBox*    subSamplingCB;
0061 
0062     DIntNumInput* JPEGcompression;
0063 };
0064 
0065 DImgJPEGExportSettings::DImgJPEGExportSettings(QWidget* const parent)
0066     : DImgLoaderSettings(parent),
0067       d                 (new Private)
0068 {
0069     const int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0070                              QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
0071 
0072     d->JPEGGrid             = new QGridLayout(this);
0073     d->JPEGcompression      = new DIntNumInput(this);
0074     d->JPEGcompression->setDefaultValue(75);
0075     d->JPEGcompression->setRange(1, 100, 1);
0076     d->labelJPEGcompression = new QLabel(i18n("JPEG quality:"), this);
0077 
0078     d->JPEGcompression->setWhatsThis(i18n("<p>The JPEG quality:</p>"
0079                                           "<p><b>1</b>: low quality (high compression and small "
0080                                           "file size)<br/>"
0081                                           "<b>50</b>: medium quality<br/>"
0082                                           "<b>75</b>: good quality (default)<br/>"
0083                                           "<b>100</b>: high quality (no compression and "
0084                                           "large file size)</p>"
0085                                           "<p><b>Note: JPEG always uses lossy compression.</b></p>"));
0086 
0087     d->labelWarning = new QLabel(i18n("<font color='red'><i>"
0088                                       "Warning: <a href='https://en.wikipedia.org/wiki/JPEG'>JPEG</a> is a "
0089                                       "lossy image compression format."
0090                                       "</i></font>"), this);
0091 
0092     d->labelWarning->setOpenExternalLinks(true);
0093     d->labelWarning->setFrameStyle(QFrame::Box | QFrame::Plain);
0094     d->labelWarning->setLineWidth(1);
0095     d->labelWarning->setFrameShape(QFrame::Box);
0096 
0097     d->labelSubSampling = new QLabel(i18n("Chroma subsampling:"), this);
0098 
0099     d->subSamplingCB = new QComboBox(this);
0100     d->subSamplingCB->insertItem(0, i18n("4:4:4 (best quality)")); // 1x1, 1x1, 1x1 (4:4:4)
0101     d->subSamplingCB->insertItem(1, i18n("4:2:2 (good quality)")); // 2x1, 1x1, 1x1 (4:2:2)
0102     d->subSamplingCB->insertItem(2, i18n("4:2:0 (low quality)"));  // 2x2, 1x1, 1x1 (4:2:0)
0103     d->subSamplingCB->insertItem(3, i18n("4:1:1 (low quality)"));  // 4x1, 1x1, 1x1 (4:1:1)
0104     d->subSamplingCB->setWhatsThis(i18n("<p>Chroma subsampling reduces file size by taking advantage of the "
0105                                         "eye's lesser sensitivity to color resolution. How perceptible the "
0106                                         "difference is depends on the image - large photos will generally "
0107                                         "show no difference, while sharp, down-scaled pixel graphics may "
0108                                         "lose fine color detail.</p>"
0109                                         "<p><b>4:4:4</b> - No chroma subsampling, highest "
0110                                         "quality but lowest compression.</p>"
0111                                         "<p><b>4:2:2</b> - Chroma halved horizontally, average "
0112                                         "compression, average quality.</p>"
0113                                         "<p><b>4:2:0</b> - Chroma quartered in 2x2 blocks, "
0114                                         "high compression but low quality.</p>"
0115                                         "<p><b>4:1:1</b> - Chroma quartered in 4x1 blocks, "
0116                                         "high compression but low quality.</p>"
0117                                         "<p><b>Note: JPEG always uses lossy compression.</b></p>"));
0118 
0119     d->JPEGGrid->addWidget(d->labelJPEGcompression, 0, 0, 1, 2);
0120     d->JPEGGrid->addWidget(d->JPEGcompression,      1, 0, 1, 2);
0121     d->JPEGGrid->addWidget(d->labelSubSampling,     2, 0, 1, 2);
0122     d->JPEGGrid->addWidget(d->subSamplingCB,        3, 0, 1, 2);
0123     d->JPEGGrid->addWidget(d->labelWarning,         4, 0, 1, 1);
0124     d->JPEGGrid->setColumnStretch(1, 10);
0125     d->JPEGGrid->setRowStretch(5, 10);
0126     d->JPEGGrid->setContentsMargins(spacing, spacing, spacing, spacing);
0127     d->JPEGGrid->setSpacing(spacing);
0128 
0129     connect(d->JPEGcompression, SIGNAL(valueChanged(int)),
0130             this, SIGNAL(signalSettingsChanged()));
0131 
0132     connect(d->subSamplingCB, SIGNAL(activated(int)),
0133             this, SIGNAL(signalSettingsChanged()));
0134 }
0135 
0136 DImgJPEGExportSettings::~DImgJPEGExportSettings()
0137 {
0138     delete d;
0139 }
0140 
0141 void DImgJPEGExportSettings::setSettings(const DImgLoaderPrms& set)
0142 {
0143     for (DImgLoaderPrms::const_iterator it = set.constBegin() ; it != set.constEnd() ; ++it)
0144     {
0145         if      (it.key() == QLatin1String("quality"))
0146         {
0147             d->JPEGcompression->setValue(it.value().toInt());
0148         }
0149         else if (it.key() == QLatin1String("subsampling"))
0150         {
0151             d->subSamplingCB->setCurrentIndex(it.value().toInt());
0152         }
0153     }
0154 }
0155 
0156 DImgLoaderPrms DImgJPEGExportSettings::settings() const
0157 {
0158     DImgLoaderPrms set;
0159     set.insert(QLatin1String("quality"),     d->JPEGcompression->value());
0160     set.insert(QLatin1String("subsampling"), d->subSamplingCB->currentIndex());
0161 
0162     return set;
0163 }
0164 
0165 } // namespace Digikam
0166 
0167 #include "moc_dimgjpegexportsettings.cpp"