diff --git a/toonz/sources/toonz/cameracapturelevelcontrol.cpp b/toonz/sources/toonz/cameracapturelevelcontrol.cpp index 3714154..b9746fd 100644 --- a/toonz/sources/toonz/cameracapturelevelcontrol.cpp +++ b/toonz/sources/toonz/cameracapturelevelcontrol.cpp @@ -399,4 +399,35 @@ void CameraCaptureLevelControl::computeLut() { p[i] = (uchar)std::floor(value * maxChannelValueF); } +} + +//----------------------------------------------------------------------------- + +void CameraCaptureLevelControl::getValues(int& black, int& white, + int& threshold, double& gamma) { + black = m_histogram->black(); + white = m_histogram->white(); + threshold = m_histogram->threshold(); + gamma = (double)m_histogram->gamma(); +} + +//----------------------------------------------------------------------------- + +void CameraCaptureLevelControl::setValues(const int black, const int white, + const int threshold, + const double gamma, + const bool color_grayscale) { + m_whiteFld->setRange(black + 2, 255); + m_blackFld->setRange(0, white - 2); + m_blackFld->setValue(black); + m_whiteFld->setValue(white); + m_gammaFld->setValue(gamma); + m_thresholdFld->setValue(threshold); + + m_histogram->setValues(m_blackFld->getValue(), m_whiteFld->getValue(), + m_gammaFld->getValue()); + m_histogram->setThreshold(m_thresholdFld->getValue()); + + setMode(color_grayscale); + computeLut(); } \ No newline at end of file diff --git a/toonz/sources/toonz/cameracapturelevelcontrol.h b/toonz/sources/toonz/cameracapturelevelcontrol.h index 5e3c191..f89031a 100644 --- a/toonz/sources/toonz/cameracapturelevelcontrol.h +++ b/toonz/sources/toonz/cameracapturelevelcontrol.h @@ -89,6 +89,11 @@ public: void adjustLevel(cv::Mat& image); void binarize(cv::Mat& image); + // for saving / loading default + void getValues(int& black, int& white, int& threshold, double& gamma); + void setValues(const int black, const int white, const int threshold, + const double gamma, const bool color_grayscale); + protected slots: void onHistogramValueChanged(int itemId); void onFieldChanged(); diff --git a/toonz/sources/toonz/icons/dark/actions/16/gear_check.svg b/toonz/sources/toonz/icons/dark/actions/16/gear_check.svg new file mode 100644 index 0000000..885734b --- /dev/null +++ b/toonz/sources/toonz/icons/dark/actions/16/gear_check.svg @@ -0,0 +1,56 @@ + + + + + + + + + diff --git a/toonz/sources/toonz/penciltestpopup.cpp b/toonz/sources/toonz/penciltestpopup.cpp index 84e6a94..a96098e 100644 --- a/toonz/sources/toonz/penciltestpopup.cpp +++ b/toonz/sources/toonz/penciltestpopup.cpp @@ -124,6 +124,7 @@ TEnv::IntVar CamCapDoCalibration("CamCapDoCalibration", 0); TEnv::RectVar CamCapSubCameraRect("CamCapSubCameraRect", TRect()); TEnv::IntVar CamCapDoAutoDpi("CamCapDoAutoDpi", 1); TEnv::DoubleVar CamCapCustomDpi("CamCapDpiForNewLevel", 120.0); +TEnv::StringVar CamCapFileType("CamCapFileType", "jpg"); namespace { @@ -433,6 +434,38 @@ protected: } }; +// https://stackoverflow.com/a/50848100/6622587 +cv::Mat QImageToMat(const QImage& image) { + cv::Mat out; + switch (image.format()) { + case QImage::Format_Invalid: { + cv::Mat empty; + empty.copyTo(out); + break; + } + case QImage::Format_RGB32: { + cv::Mat view(image.height(), image.width(), CV_8UC4, + (void*)image.constBits(), image.bytesPerLine()); + view.copyTo(out); + break; + } + case QImage::Format_RGB888: { + cv::Mat view(image.height(), image.width(), CV_8UC3, + (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(view, out, cv::COLOR_RGB2BGR); + break; + } + default: { + QImage conv = image.convertToFormat(QImage::Format_ARGB32); + cv::Mat view(conv.height(), conv.width(), CV_8UC4, (void*)conv.constBits(), + conv.bytesPerLine()); + view.copyTo(out); + break; + } + } + return out; +} + } // namespace //============================================================================= @@ -1556,8 +1589,9 @@ PencilTestPopup::PencilTestPopup() m_saveOnCaptureCB = new QCheckBox(tr("Save images as they are captured"), this); - QGroupBox* imageFrame = new QGroupBox(tr("Image adjust"), this); - m_colorTypeCombo = new QComboBox(this); + QGroupBox* imageFrame = new QGroupBox(tr("Image adjust"), this); + m_colorTypeCombo = new QComboBox(this); + m_saveImgAdjustDefaultButton = new QPushButton(this); m_camCapLevelControl = new CameraCaptureLevelControl(this); m_upsideDownCB = new QCheckBox(tr("Upside down"), this); @@ -1610,7 +1644,7 @@ PencilTestPopup::PencilTestPopup() m_resolutionCombo->setMaximumWidth(fontMetrics().width("0000 x 0000") + 25); m_fileTypeCombo->addItems({"jpg", "png", "tga", "tif"}); - m_fileTypeCombo->setCurrentIndex(0); + m_fileTypeCombo->setCurrentText(QString::fromStdString(CamCapFileType)); fileFrame->setObjectName("CleanupSettingsFrame"); m_frameNumberEdit->setObjectName("LargeSizedText"); @@ -1627,6 +1661,11 @@ PencilTestPopup::PencilTestPopup() m_colorTypeCombo->addItems( {tr("Color"), tr("Grayscale"), tr("Black & White")}); m_colorTypeCombo->setCurrentIndex(0); + m_saveImgAdjustDefaultButton->setFixedSize(24, 24); + m_saveImgAdjustDefaultButton->setIconSize(QSize(16, 16)); + m_saveImgAdjustDefaultButton->setIcon(createQIcon("gear_check")); + m_saveImgAdjustDefaultButton->setToolTip( + tr("Save Current Image Adjust Parameters As Default")); m_upsideDownCB->setChecked(false); m_bgReductionFld->setRange(0, 100); @@ -1824,6 +1863,8 @@ PencilTestPopup::PencilTestPopup() imageLay->addWidget(new QLabel(tr("Color type:"), this), 0, 0, Qt::AlignRight); imageLay->addWidget(m_colorTypeCombo, 0, 1); + imageLay->addWidget(m_saveImgAdjustDefaultButton, 0, 2, + Qt::AlignRight); imageLay->addWidget(m_camCapLevelControl, 1, 0, 1, 3); @@ -1918,6 +1959,8 @@ PencilTestPopup::PencilTestPopup() SLOT(onPreviousName())); ret = ret && connect(m_colorTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onColorTypeComboChanged(int))); + ret = ret && connect(m_saveImgAdjustDefaultButton, SIGNAL(pressed()), this, + SLOT(saveImageAdjustDefault())); ret = ret && connect(m_captureWhiteBGButton, SIGNAL(pressed()), this, SLOT(onCaptureWhiteBGButtonPressed())); ret = ret && connect(m_onionSkinGBox, SIGNAL(toggled(bool)), this, @@ -1942,8 +1985,12 @@ PencilTestPopup::PencilTestPopup() SLOT(openSaveInFolderPopup())); ret = ret && connect(m_saveInFileFld, SIGNAL(pathChanged()), this, SLOT(onSaveInPathEdited())); - ret = ret && connect(m_fileTypeCombo, SIGNAL(activated(int)), this, - SLOT(refreshFrameInfo())); + ret = ret && + connect(m_fileTypeCombo, QOverload::of(&QComboBox::activated), + [&](int index) { + CamCapFileType = m_fileTypeCombo->currentText().toStdString(); + refreshFrameInfo(); + }); ret = ret && connect(m_frameNumberEdit, SIGNAL(editingFinished()), this, SLOT(refreshFrameInfo())); @@ -2040,6 +2087,9 @@ PencilTestPopup::PencilTestPopup() m_videoWidget->setImage(dummyImg); m_subcameraButton->setChecked(true); } + + // try loading the default parameter + loadImageAdjustDefault(); } } @@ -3466,6 +3516,13 @@ void PencilTestPopup::onSaveInPathEdited() { //----------------------------------------------------------------------------- +void PencilTestPopup::onFileTypeChanged() { + CamCapFileType = m_fileTypeCombo->currentText().toStdString(); + refreshFrameInfo(); +} + +//----------------------------------------------------------------------------- + void PencilTestPopup::onSceneSwitched() { m_saveInFolderPopup->updateParentFolder(); m_saveInFileFld->setPath(m_saveInFolderPopup->getParentPath()); @@ -3616,14 +3673,33 @@ void PencilTestPopup::resetCalibSettingsFromFile() { //----------------------------------------------------------------------------- -QString PencilTestPopup::getCurrentCalibFilePath() { +QString PencilTestPopup::getCameraConfigurationPath(const QString& folderName, + const QString& ext) { QString cameraName = m_cameraListCombo->currentText(); if (cameraName.isEmpty()) return QString(); QString resolution = m_resolutionCombo->currentText(); QString hostName = QHostInfo::localHostName(); - TFilePath folderPath = ToonzFolder::getLibraryFolder() + "camera calibration"; - return folderPath.getQString() + "\\" + hostName + "_" + cameraName + "_" + - resolution + ".xml"; + TFilePath folderPath = ToonzFolder::getLibraryFolder(); + return folderPath.getQString() + "\\" + folderName + "\\" + hostName + "_" + + cameraName + "_" + resolution + "." + ext; +} + +//----------------------------------------------------------------------------- + +QString PencilTestPopup::getCurrentCalibFilePath() { + return getCameraConfigurationPath("camera calibration", "xml"); +} + +//----------------------------------------------------------------------------- + +QString PencilTestPopup::getImageAdjustSettingsPath() { + return getCameraConfigurationPath("camera image adjust", "ini"); +} + +//----------------------------------------------------------------------------- + +QString PencilTestPopup::getImageAdjustBgImgPath() { + return getCameraConfigurationPath("camera image adjust", "jpg"); } //----------------------------------------------------------------------------- @@ -3789,6 +3865,80 @@ void PencilTestPopup::onPreferenceChanged(const QString& prefName) { } //----------------------------------------------------------------------------- +// called in ctor +void PencilTestPopup::loadImageAdjustDefault() { + // find the configuration file + QString settingsPath = getImageAdjustSettingsPath(); + if (!TFileStatus(TFilePath(settingsPath)).doesExist()) return; + + QSettings imgAdjSettings(settingsPath, QSettings::IniFormat); + int colorType = imgAdjSettings.value("ColorType", 0).toInt(); + int black = imgAdjSettings.value("BlackLevel", 0).toInt(); + int white = imgAdjSettings.value("WhiteLevel", 255).toInt(); + double gamma = imgAdjSettings.value("Gamma", 1.0).toDouble(); + int threshold = imgAdjSettings.value("Threshold", 128).toInt(); + bool upsideDown = imgAdjSettings.value("UpsideDown", false).toBool(); + int bgReduction = imgAdjSettings.value("BgReduction", 0).toInt(); + + m_colorTypeCombo->setCurrentIndex(colorType); + m_camCapLevelControl->setValues(black, white, threshold, gamma, + colorType != 2); + m_upsideDownCB->setChecked(upsideDown); + m_bgReductionFld->setValue(bgReduction); + + QString bgPath = getImageAdjustBgImgPath(); + if (!TFileStatus(TFilePath(bgPath)).doesExist()) { + if (bgReduction > 0) + warning( + tr("BG Reduction is set but the White BG image is missing. Please " + "capture the White BG again.")); + + m_whiteBGImg = cv::Mat(); + m_bgReductionFld->setDisabled(true); + return; + } + + QImage bgImg(bgPath); + if (bgImg.isNull()) { + m_whiteBGImg = cv::Mat(); + m_bgReductionFld->setDisabled(true); + return; + } + cv::Mat tmpMat = QImageToMat(bgImg); + cv::cvtColor(tmpMat, m_whiteBGImg, cv::COLOR_RGBA2RGB); + m_bgReductionFld->setEnabled(true); +} + +//----------------------------------------------------------------------------- + +void PencilTestPopup::saveImageAdjustDefault() { + QString question = + tr("Do you want to save the current parameters as the default values?"); + int ret = DVGui::MsgBox(question, QObject::tr("Save"), QObject::tr("Cancel")); + if (ret == 0 || ret == 2) return; + + QString settingsPath = getImageAdjustSettingsPath(); + QSettings imgAdjSettings(settingsPath, QSettings::IniFormat); + + imgAdjSettings.setValue("ColorType", m_colorTypeCombo->currentIndex()); + int black, white, threshold; + double gamma; + m_camCapLevelControl->getValues(black, white, threshold, gamma); + imgAdjSettings.setValue("BlackLevel", black); + imgAdjSettings.setValue("WhiteLevel", white); + imgAdjSettings.setValue("Gamma", gamma); + imgAdjSettings.setValue("Threshold", threshold); + imgAdjSettings.setValue("UpsideDown", m_upsideDownCB->isChecked()); + imgAdjSettings.setValue("BgReduction", m_bgReductionFld->getValue()); + + if (!m_whiteBGImg.empty()) { + QImage qimg(m_whiteBGImg.data, m_whiteBGImg.cols, m_whiteBGImg.rows, + QImage::Format_RGB888); + qimg.save(getImageAdjustBgImgPath()); + } +} + +//----------------------------------------------------------------------------- OpenPopupCommandHandler openPencilTestPopup(MI_PencilTest); diff --git a/toonz/sources/toonz/penciltestpopup.h b/toonz/sources/toonz/penciltestpopup.h index 60fe140..397cb97 100644 --- a/toonz/sources/toonz/penciltestpopup.h +++ b/toonz/sources/toonz/penciltestpopup.h @@ -271,7 +271,7 @@ class PencilTestPopup : public DVGui::Dialog { QCheckBox *m_upsideDownCB, *m_saveOnCaptureCB; QGroupBox *m_onionSkinGBox, *m_timerGBox; QPushButton *m_fileFormatOptionButton, *m_captureWhiteBGButton, - *m_captureButton, *m_loadImageButton; + *m_captureButton, *m_loadImageButton, *m_saveImgAdjustDefaultButton; DVGui::FileField* m_saveInFileFld; FrameNumberLineEdit* m_frameNumberEdit; DVGui::IntField *m_bgReductionFld, *m_onionOpacityFld, *m_timerIntervalFld; @@ -341,8 +341,13 @@ class PencilTestPopup : public DVGui::Dialog { QMenu* createOptionsMenu(); int translateIndex(int camIndex); + void loadImageAdjustDefault(); QString getCurrentCalibFilePath(); + QString getImageAdjustSettingsPath(); + QString getImageAdjustBgImgPath(); + QString getCameraConfigurationPath(const QString& folderName, + const QString& ext); QWidget* createDpiMenuWidget(); @@ -381,6 +386,7 @@ protected slots: void refreshFrameInfo(); void onSaveInPathEdited(); + void onFileTypeChanged(); void onSceneSwitched(); void onSubCameraToggled(bool); @@ -398,6 +404,8 @@ protected slots: void onCalibReadme(); void onPreferenceChanged(const QString&); + void saveImageAdjustDefault(); + public slots: void openSaveInFolderPopup(); }; diff --git a/toonz/sources/toonz/toonz.qrc b/toonz/sources/toonz/toonz.qrc index 708740e..3335a78 100644 --- a/toonz/sources/toonz/toonz.qrc +++ b/toonz/sources/toonz/toonz.qrc @@ -75,7 +75,8 @@ icons/dark/actions/16/save.svg icons/dark/actions/16/saveas.svg icons/dark/actions/16/saveall.svg - icons/dark/actions/16/gear.svg + icons/dark/actions/16/gear.svg + icons/dark/actions/16/gear_check.svg icons/dark/actions/16/settings_reset.svg icons/dark/actions/16/clear.svg icons/dark/actions/16/undo.svg