Skip to content

Commit

Permalink
Add a save default DNG options feature.
Browse files Browse the repository at this point in the history
- The DNG options can be saved as the default values for the next images.
- The file name for the mask can contain tokens that are replaced by the name and directory of the output file and the least exposed image.
  • Loading branch information
jcelaya committed May 24, 2014
1 parent bdb20f3 commit 18fc46f
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 14 deletions.
45 changes: 36 additions & 9 deletions DngPropertiesDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,30 @@
#include <QButtonGroup>
#include <QPushButton>
#include <QFileDialog>
#include <QCheckBox>
#include <QSettings>
#include "DngPropertiesDialog.hpp"

namespace hdrmerge {

DngPropertiesDialog::DngPropertiesDialog(QWidget * parent, Qt::WindowFlags f)
: QDialog(parent, f), SaveOptions() {
loadDefaultOptions();

QVBoxLayout * layout = new QVBoxLayout(this);

QWidget * bpsSelector = new QWidget(this);
QHBoxLayout * bpsSelectorLayout = new QHBoxLayout(bpsSelector);
bpsSelectorLayout->setMargin(0);
QButtonGroup * bpsGroup = new QButtonGroup(this);
const char * buttonLabels[] = { "16", "24", "32" };
int bpsIndex = (bps - 16) / 8;;
for (int i = 0; i < 3; ++i) {
QRadioButton * button = new QRadioButton(buttonLabels[i], this);
button->setChecked(i == 0);
button->setChecked(i == bpsIndex);
bpsGroup->addButton(button, i);
bpsSelectorLayout->addWidget(button);
}
connect(bpsGroup, SIGNAL(buttonClicked( int)), this, SLOT(setBps(int)));
bps = 16;
connect(bpsGroup, SIGNAL(buttonClicked(int)), this, SLOT(setBps(int)));

QWidget * previewSelector = new QWidget(this);
QHBoxLayout * previewSelectorLayout = new QHBoxLayout(previewSelector);
Expand All @@ -56,12 +58,11 @@ DngPropertiesDialog::DngPropertiesDialog(QWidget * parent, Qt::WindowFlags f)
const char * previewLabels[] = { "Full", "Half", "None" };
for (int i = 0; i < 3; ++i) {
QRadioButton * button = new QRadioButton(tr(previewLabels[i]), this);
button->setChecked(i == 0);
button->setChecked(i == (2 - previewSize));
previewGroup->addButton(button, 2 - i);
previewSelectorLayout->addWidget(button);
}
connect(previewGroup, SIGNAL(buttonClicked( int)), this, SLOT(setPreviewSize(int)));
previewSize = 2;

QCheckBox * saveMaskFile = new QCheckBox(tr("Save"), this);

Expand All @@ -70,12 +71,19 @@ DngPropertiesDialog::DngPropertiesDialog(QWidget * parent, Qt::WindowFlags f)
maskFileSelectorLayout->setMargin(0);
maskFileEditor = new QLineEdit(maskFileSelector);
maskFileEditor->setMinimumWidth(200);
maskFileEditor->setToolTip(tr("You can use the following tokens:") + "\n" +
"- %if " + tr("for the file name of the least exposed image.") + "\n" +
"- %id " + tr("for the directory name of the least exposed image.") + "\n" +
"- %of " + tr("for the file name of the result image.") + "\n" +
"- %od " + tr("for the directory name of the result image."));
maskFileEditor->setText(maskFileName.c_str());
QPushButton * showFileDialog = new QPushButton("...", maskFileSelector);
connect(showFileDialog, SIGNAL(clicked(bool)), this, SLOT(setMaskFileName()));
maskFileSelectorLayout->addWidget(maskFileEditor);
maskFileSelectorLayout->addWidget(showFileDialog);
connect(saveMaskFile, SIGNAL(stateChanged(int)), this, SLOT(setMaskFileSelectorEnabled(int)));
maskFileSelector->setEnabled(false);
saveMaskFile->setChecked(saveMask);
maskFileSelector->setEnabled(saveMask);

QWidget * formWidget = new QWidget(this);
QFormLayout * formLayout = new QFormLayout(formWidget);
Expand All @@ -86,6 +94,9 @@ DngPropertiesDialog::DngPropertiesDialog(QWidget * parent, Qt::WindowFlags f)
formWidget->setLayout(formLayout);
layout->addWidget(formWidget, 1);

saveOptions = new QCheckBox(tr("Save these options as the default values."));
layout->addWidget(saveOptions, 0, Qt::AlignLeft);

QWidget * buttons = new QWidget(this);
QHBoxLayout * buttonsLayout = new QHBoxLayout(buttons);
QPushButton * acceptButton = new QPushButton(tr("Accept"), this);
Expand All @@ -103,12 +114,28 @@ DngPropertiesDialog::DngPropertiesDialog(QWidget * parent, Qt::WindowFlags f)


void DngPropertiesDialog::accept() {
maskFileName = maskFileSelector->isEnabled() ?
QDir::toNativeSeparators(maskFileEditor->text()).toUtf8().constData() : "";
saveMask = maskFileSelector->isEnabled();
maskFileName = QDir::toNativeSeparators(maskFileEditor->text()).toUtf8().constData();
if (saveOptions->isChecked()) {
QSettings settings;
settings.setValue("bps", bps);
settings.setValue("previewSize", previewSize);
settings.setValue("saveMask", saveMask);
settings.setValue("maskFileName", maskFileName.c_str());
}
QDialog::accept();
}


void DngPropertiesDialog::loadDefaultOptions() {
QSettings settings;
bps = settings.value("bps", 16).toInt();
previewSize = settings.value("previewSize", 2).toInt();
saveMask = settings.value("saveMask", false).toBool();
maskFileName = settings.value("maskFileName", "%od/%of_mask.png").toString().toUtf8().constData();
}


void DngPropertiesDialog::setBps(int i) {
switch (i) {
case 0: bps = 16; break;
Expand Down
4 changes: 4 additions & 0 deletions DngPropertiesDialog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <QDialog>
#include <QLineEdit>
#include <QCheckBox>
#include "LoadSaveOptions.hpp"

namespace hdrmerge {
Expand All @@ -50,9 +51,12 @@ private slots:

private:
Q_OBJECT

void loadDefaultOptions();

QLineEdit * maskFileEditor;
QWidget * maskFileSelector;
QCheckBox * saveOptions;
};

} // namespace hdrmerge
Expand Down
41 changes: 38 additions & 3 deletions ImageStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,10 @@ int ImageStack::save(const SaveOptions & options, ProgressIndicator & progress)
writer.setBitsPerSample(options.bps);
writer.setPreviewWidth((options.previewSize * width) / 2);
writer.write(options.fileName);
if (!options.maskFileName.empty()) {
Log::msg(Log::DEBUG, "Saving mask to ", options.maskFileName);
mask.writeMaskImage(options.maskFileName);
if (options.saveMask) {
string name = replaceArguments(options.maskFileName, options.fileName);
Log::msg(Log::DEBUG, "Saving mask to ", name);
mask.writeMaskImage(name);
}
}

Expand Down Expand Up @@ -222,3 +223,37 @@ string ImageStack::buildOutputFileName() const {
}
return name;
}


string ImageStack::replaceArguments(const string & maskFileName, const string & outFileName) {
string result = maskFileName;
const char * specs[4] = {
"%if",
"%id",
"%of",
"%od"
};
string names[4];
string inFileName = images.back()->getMetaData().fileName;
size_t index = inFileName.find_last_of('/');
if (index != string::npos) {
names[1] = inFileName.substr(0, index);
names[0] = inFileName.substr(index + 1);
} else {
names[0] = inFileName;
}
index = outFileName.find_last_of('/');
if (index != string::npos) {
names[3] = outFileName.substr(0, index);
names[2] = outFileName.substr(index + 1);
} else {
names[2] = outFileName;
}
// Replace specifiers
for (int i = 0; i < 4; ++i) {
while ((index = result.find(specs[i])) != string::npos) {
result.replace(index, 3, names[i]);
}
}
return result;
}
2 changes: 2 additions & 0 deletions ImageStack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ class ImageStack {
size_t width;
size_t height;
uint8_t toneCurve[65536];

std::string replaceArguments(const std::string & maskFileName, const std::string & outFileName);
};

} // namespace hdrmerge
Expand Down
3 changes: 2 additions & 1 deletion LoadSaveOptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ struct SaveOptions {
int bps;
int previewSize;
std::string fileName;
bool saveMask;
std::string maskFileName;
SaveOptions() : bps(16), previewSize(0) {}
SaveOptions() : bps(16), previewSize(0), saveMask(false) {}
};

} // namespace hdrmerge
Expand Down
1 change: 0 additions & 1 deletion MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,6 @@ void MainWindow::saveResult() {
fileName += ".dng";
}
DngPropertiesDialog dpd(this);
dpd.setMaskFileName((images->buildOutputFileName() + "_mask.png").c_str());
if (dpd.exec()) {
dpd.fileName = fileName;
ProgressDialog pd(this);
Expand Down
24 changes: 24 additions & 0 deletions hdrmerge_es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,30 @@
<source>Save</source>
<translation type="finished">Guardar</translation>
</message>
<message>
<source>Save these options as the default values.</source>
<translation type="finished">Guardar estas opciones como los valores por defecto.</translation>
</message>
<message>
<source>You can use the following tokens:</source>
<translation type="finished">Puede utilizar los siguientes símbolos:</translation>
</message>
<message>
<source>for the file name of the least exposed image.</source>
<translation type="finished">para el nombre de fichero de la imagen menos expuesta.</translation>
</message>
<message>
<source>for the directory name of the least exposed image.</source>
<translation type="finished">para el nombre de directorio de la imagen menos expuesta.</translation>
</message>
<message>
<source>for the file name of the result image.</source>
<translation type="finished">para el nombre de fichero de la imagen resultado.</translation>
</message>
<message>
<source>for the directory name of the result image.</source>
<translation type="finished">para el nombre de directorio de la imagen resultado.</translation>
</message>
</context>
<context>
<name>hdrmerge::MainWindow</name>
Expand Down

0 comments on commit 18fc46f

Please sign in to comment.