Skip to content

Commit

Permalink
#48 JPEG advanced options and options toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
mattrussmill committed Jul 7, 2019
1 parent ce958c0 commit 38fed4f
Show file tree
Hide file tree
Showing 9 changed files with 555 additions and 38 deletions.
69 changes: 58 additions & 11 deletions imagesavedialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,29 @@
#include "imagesavejpegmenu.h"
#include "imagesavepngmenu.h"
#include "imagesavewebpmenu.h"
#include <QStackedLayout>
#include <QStackedWidget>
#include <QGridLayout>
#include <QPushButton>
#include <QDebug>
#include <opencv2/imgcodecs.hpp>

ImageSaveDialog::ImageSaveDialog(QImage &image, QWidget *parent)
: QFileDialog(parent)
{
setOption(QFileDialog::DontUseNativeDialog);
setAcceptMode(QFileDialog::AcceptSave);
setNameFilter("All Files (*);;Bitmap (*.bmp *.dib);;JPEG(*.jpeg *.jpg *.jpe);;PNG (*.png)");
appendImageOptionsWidget();

setNameFilter("JPEG(*.jpeg *.jpg *.jpe);;PNG (*.png);;WebP (*.webp);;All Files (*)");
appendAdvancedOptionsButton();

}

ImageSaveDialog::ImageSaveDialog(QImage &image, QWidget *parent, const QString &caption, const QString &directory)
: QFileDialog (parent, caption, directory, "All Files (*);;JPEG(*.jpeg *.jpg *.jpe);;PNG (*.png);;WebP (*.webp)")
: QFileDialog (parent, caption, directory, "JPEG(*.jpeg *.jpg *.jpe);;PNG (*.png);;WebP (*.webp);;All Files (*)")
{
//must set to not use native dialog so that we can access the dialog's layout
setOption(QFileDialog::DontUseNativeDialog);
setAcceptMode(QFileDialog::AcceptSave);
appendImageOptionsWidget();
appendAdvancedOptionsButton();
}

ImageSaveDialog::~ImageSaveDialog()
Expand All @@ -47,8 +48,55 @@ void ImageSaveDialog::saveBitmap(QImage &image)

}

/* If the advanced options do not exist, create them. If they do exist,
* toggle their visibility*/
void ImageSaveDialog::advancedOptionsToggled()
{
if(!saveOptionsWidget_m)
{
appendImageOptionsWidget();
buttonAdvancedOptions_m->setText("Hide...");
}
else if(!saveOptionsWidget_m->isVisible())
{
saveOptionsWidget_m->setVisible(true);
buttonAdvancedOptions_m->setText("Hide...");
}
else
{
saveOptionsWidget_m->setVisible(false);
buttonAdvancedOptions_m->setText("Advanced...");
}
}

/* this method is used by the constructor and appends the "Advanced..." dialog
* button to the dialog in the bottom right corner of the layout below "Cancel"*/
void ImageSaveDialog::appendAdvancedOptionsButton()
{
//get main layout of QFileDialog
QGridLayout* mainLayout = dynamic_cast<QGridLayout*>(this->layout());

if(!mainLayout)
{
qDebug()<<"mainLayout is unavailable";
}
else
{
buttonAdvancedOptions_m = new QPushButton("Advanced...", this);
int rows = mainLayout->rowCount();
int columns = mainLayout->columnCount();
mainLayout->addWidget(buttonAdvancedOptions_m, rows, columns - 1, 1, -1);

//connect the button functionality
connect(buttonAdvancedOptions_m, SIGNAL(released()), this, SLOT(advancedOptionsToggled()));
}
}

/* this method generates and adds the advanced options widgets to the save dialog for the
* supported image formats */
void ImageSaveDialog::appendImageOptionsWidget()
{
//get main layout of QFileDialog
QGridLayout* mainLayout = dynamic_cast<QGridLayout*>(this->layout());

if(!mainLayout)
Expand All @@ -57,12 +105,11 @@ void ImageSaveDialog::appendImageOptionsWidget()
}
else
{
saveOptionsLayout_m = new QStackedLayout(this); //do not put in initialization list
//webpUi_m = new Ui::ImageSaveWebpMenu; ??
//saveOptionsLayout_m->addWidget(webpMenu_m);
saveOptionsWidget_m = new QStackedWidget(this); //do not put in initialization list
jpegMenu_m = new ImageSaveJpegMenu(this);
saveOptionsWidget_m->addWidget(jpegMenu_m);
int rows = mainLayout->rowCount();
qDebug() << "save dialog g-layout rows: " << rows;
mainLayout->addLayout(saveOptionsLayout_m, rows, 0, 1, -1);
mainLayout->addWidget(saveOptionsWidget_m, rows, 0, 1, -1);
}

}
16 changes: 11 additions & 5 deletions imagesavedialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
#define IMAGESAVEDIALOG_H

#include <QFileDialog>
class QStackedLayout;
class QStackedWidget;
class QPushButton;
class ImageSaveJpegMenu;
class ImageSavePngMenu;
class ImageSaveWebpMenu;
Expand All @@ -21,13 +22,18 @@ class ImageSaveDialog : public QFileDialog
void saveBitmap(QImage &image);
void savePNG(QImage &image);

private slots:
void advancedOptionsToggled();

private:
enum ImageType{JPEG, PNG, WEBP};
void appendImageOptionsWidget();
QStackedLayout *saveOptionsLayout_m;
ImageSaveJpegMenu *jpegMenu_m;
ImageSavePngMenu *pngMenu_m;
ImageSaveWebpMenu *webpMenu_m;
void appendAdvancedOptionsButton();
QPushButton *buttonAdvancedOptions_m = nullptr;
QStackedWidget *saveOptionsWidget_m = nullptr;
ImageSaveJpegMenu *jpegMenu_m = nullptr;
ImageSavePngMenu *pngMenu_m = nullptr;
ImageSaveWebpMenu *webpMenu_m = nullptr;

};

Expand Down
119 changes: 118 additions & 1 deletion imagesavejpegmenu.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,132 @@
/***********************************************************************
* FILENAME : imagesavejpegmenu.cpp
*
* LICENSE:
* qcvTouchUp provides an image processing toolset for editing
* photographs, purposed and packaged for use in a desktop application
* user environment. Copyright (C) 2018, Matthew R. Miller
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation (version 3 of the License) and the
* 3-clause BSD License as agreed upon through the use of the Qt toolkit
* and OpenCV libraries in qcvTouchUp development, respectively. Copies
* of the appropriate license files for qcvTouchup, and its source code,
* can be found in LICENSE.Qt.txt and LICENSE.CV.txt.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License and
* 3-clause BSD License along with this program. If not, please see
* <http://www.gnu.org/licenses/> and <https://opencv.org/license.html>.
*
* If you wish to contact the developer about this project, please do so
* through their account at <https://github.com/mattrussmill>
*
* DESCRIPTION :
* This widget is used to collect user input parameters for saving an
* image in the JPEG file format.
*
* NOTES :
* The values captured are associated with cv::imwrite(), an OpenCV
* function.
*
*
* AUTHOR : Matthew R. Miller START DATE : March 03/04/2019
*
* CHANGES : N/A - N/A
*
* VERSION DATE WHO DETAIL
* 0.1 07/07/2019 Matthew R. Miller Initial Rev
*
************************************************************************/
#include "imagesavejpegmenu.h"
#include "ui_imagesavejpegmenu.h"
#include <opencv2/imgcodecs.hpp>
#include "mousewheeleatereventfilter.h"

ImageSaveJpegMenu::ImageSaveJpegMenu(QWidget *parent) :
QWidget(parent),
ui(new Ui::ImageSaveJpegMenu)
{
ui->setupUi(this);

//install event filter
MouseWheelEaterEventFilter *filter = new MouseWheelEaterEventFilter(this);
ui->horizontalSlider_Quality->installEventFilter(filter);
ui->horizontalSlider_RestartInterval->installEventFilter(filter);
ui->horizontalSlider_Chroma->installEventFilter(filter);
ui->horizontalSlider_Luma->installEventFilter(filter);
ui->spinBox_Quality->installEventFilter(filter);
ui->spinBox_RestartInterval->installEventFilter(filter);
ui->spinBox_Chroma->installEventFilter(filter);
ui->spinBox_Luma->installEventFilter(filter);

//initial states
ui->horizontalSlider_Chroma->setEnabled(false);
ui->spinBox_Chroma->setEnabled(false);
ui->horizontalSlider_Luma->setEnabled(false);
ui->spinBox_Luma->setEnabled(false);

//connect signals slots
connect(ui->horizontalSlider_Quality, SIGNAL(valueChanged(int)), ui->spinBox_Quality, SLOT(setValue(int)));
connect(ui->spinBox_Quality, SIGNAL(valueChanged(int)), ui->horizontalSlider_Quality, SLOT(setValue(int)));
connect(ui->horizontalSlider_RestartInterval, SIGNAL(valueChanged(int)), ui->spinBox_RestartInterval, SLOT(setValue(int)));
connect(ui->spinBox_RestartInterval, SIGNAL(valueChanged(int)), ui->horizontalSlider_RestartInterval, SLOT(setValue(int)));
connect(ui->horizontalSlider_Chroma, SIGNAL(valueChanged(int)), ui->spinBox_Chroma, SLOT(setValue(int)));
connect(ui->spinBox_Chroma, SIGNAL(valueChanged(int)), ui->horizontalSlider_Chroma, SLOT(setValue(int)));
connect(ui->horizontalSlider_Luma, SIGNAL(valueChanged(int)), ui->spinBox_Luma, SLOT(setValue(int)));
connect(ui->spinBox_Luma, SIGNAL(valueChanged(int)), ui->horizontalSlider_Luma, SLOT(setValue(int)));

connect(ui->checkBox_EnableChroma, SIGNAL(toggled(bool)), ui->horizontalSlider_Chroma, SLOT(setEnabled(bool)));
connect(ui->checkBox_EnableChroma, SIGNAL(toggled(bool)), ui->spinBox_Chroma, SLOT(setEnabled(bool)));
connect(ui->checkBox_EnableLuma, SIGNAL(toggled(bool)), ui->horizontalSlider_Luma, SLOT(setEnabled(bool)));
connect(ui->checkBox_EnableLuma, SIGNAL(toggled(bool)), ui->spinBox_Luma, SLOT(setEnabled(bool)));
}

ImageSaveJpegMenu::~ImageSaveJpegMenu()
{
delete ui;
}

//returns the overall quality value for the JPEG image - opencv between 0 - 100
int ImageSaveJpegMenu::getQuality()
{
return ui->spinBox_Quality->value();
}

//returns the restart interval for the JPEG image - opencv between 0 - 65535, 0 = none
int ImageSaveJpegMenu::getRestartInterval()
{
return ui->spinBox_RestartInterval->value();
}

//returns the quality value for the Luma channel individually - opencv between 0 - 100, 0 = done use
int ImageSaveJpegMenu::getLumaQuality()
{
if(ui->checkBox_EnableLuma->isChecked())
return ui->spinBox_Luma->value();
return 0;
}

//returns the quality value for the Chroma channel individually - opencv between 0 - 100, 0 = done use
int ImageSaveJpegMenu::getChromaQuality()
{
if(ui->checkBox_EnableChroma->isChecked())
return ui->spinBox_Chroma->value();
return 0;
}

//returns 1 if progressive scan is enabled, 0 if not used
int ImageSaveJpegMenu::getProgressiveScan()
{
return ui->checkBox_ProgressiveScan->isChecked();
}

//returns 1 if optomized baseline is enabled, 0 if not used
int ImageSaveJpegMenu::getBaselineOptimized()
{
return ui->checkBox_Optomized->isChecked();
}
51 changes: 51 additions & 0 deletions imagesavejpegmenu.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,48 @@
/***********************************************************************
* FILENAME : imagesavejpegmenu.h
*
* LICENSE:
* qcvTouchUp provides an image processing toolset for editing
* photographs, purposed and packaged for use in a desktop application
* user environment. Copyright (C) 2018, Matthew R. Miller
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation (version 3 of the License) and the
* 3-clause BSD License as agreed upon through the use of the Qt toolkit
* and OpenCV libraries in qcvTouchUp development, respectively. Copies
* of the appropriate license files for qcvTouchup, and its source code,
* can be found in LICENSE.Qt.txt and LICENSE.CV.txt.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License and
* 3-clause BSD License along with this program. If not, please see
* <http://www.gnu.org/licenses/> and <https://opencv.org/license.html>.
*
* If you wish to contact the developer about this project, please do so
* through their account at <https://github.com/mattrussmill>
*
* DESCRIPTION :
* This widget is used to collect user input parameters for saving an
* image in the JPEG file format.
*
* NOTES :
* The values captured are associated with cv::imwrite(), an OpenCV
* function.
*
*
* AUTHOR : Matthew R. Miller START DATE : March 03/04/2019
*
* CHANGES : N/A - N/A
*
* VERSION DATE WHO DETAIL
* 0.1 07/07/2019 Matthew R. Miller Initial Rev
*
************************************************************************/
#ifndef IMAGESAVEJPEGMENU_H
#define IMAGESAVEJPEGMENU_H

Expand All @@ -14,6 +59,12 @@ class ImageSaveJpegMenu : public QWidget
public:
explicit ImageSaveJpegMenu(QWidget *parent = nullptr);
~ImageSaveJpegMenu();
int getQuality();
int getRestartInterval();
int getChromaQuality();
int getLumaQuality();
int getProgressiveScan();
int getBaselineOptimized();

private:
Ui::ImageSaveJpegMenu *ui;
Expand Down
Loading

0 comments on commit 38fed4f

Please sign in to comment.