Merge pull request #782 from shun-iwasawa/camcap_modification

Camera Capture fixes
This commit is contained in:
Jeremy Bullock 2016-09-15 08:16:38 -06:00 committed by GitHub
commit 72d52f5dfc
2 changed files with 164 additions and 39 deletions

View file

@ -33,6 +33,7 @@
// TnzCore includes
#include "tsystem.h"
#include "tpixelutils.h"
#include "tenv.h"
#include <algorithm>
@ -67,6 +68,9 @@
using namespace DVGui;
// Connected camera
TEnv::StringVar CamCapCameraName("CamCapCameraName", "");
namespace {
void convertImageToRaster(TRaster32P dstRas, const QImage& srcImg) {
@ -363,7 +367,7 @@ void MyViewFinder::paintEvent(QPaintEvent* event) {
}
}
void MyViewFinder::resizeEvent(QResizeEvent* event) {
void MyViewFinder::updateSize() {
if (!m_camera) return;
QSize cameraReso = m_camera->viewfinderSettings().resolution();
double cameraAR = (double)cameraReso.width() / (double)cameraReso.height();
@ -381,6 +385,8 @@ void MyViewFinder::resizeEvent(QResizeEvent* event) {
}
}
void MyViewFinder::resizeEvent(QResizeEvent* event) { updateSize(); }
//=============================================================================
FrameNumberLineEdit::FrameNumberLineEdit(QWidget* parent, int value)
@ -449,10 +455,34 @@ void FrameNumberLineEdit::focusOutEvent(QFocusEvent*) {}
//=============================================================================
LevelNameLineEdit::LevelNameLineEdit(QWidget* parent)
: QLineEdit(parent), m_textOnFocusIn("") {
// Exclude all character which cannot fit in a filepath (Win).
// Dots are also prohibited since they are internally managed by Toonz.
QRegExp rx("[^\\\\/:?*.\"<>|]+");
setValidator(new QRegExpValidator(rx, this));
setObjectName("LargeSizedText");
connect(this, SIGNAL(editingFinished()), this, SLOT(onEditingFinished()));
}
void LevelNameLineEdit::focusInEvent(QFocusEvent* e) {
m_textOnFocusIn = text();
}
void LevelNameLineEdit::onEditingFinished() {
// if the content is not changed, do nothing.
if (text() == m_textOnFocusIn) return;
emit levelNameEdited();
}
//=============================================================================
PencilTestPopup::PencilTestPopup()
: Dialog(TApp::instance()->getMainWindow(), false, false, "PencilTest")
, m_currentCamera(0)
, m_cameraImageCapture(0)
, m_currentCamera(NULL)
, m_cameraImageCapture(NULL)
, m_captureWhiteBGCue(false)
, m_captureCue(false) {
setWindowTitle(tr("Camera Capture"));
@ -479,7 +509,7 @@ PencilTestPopup::PencilTestPopup()
m_resolutionCombo = new QComboBox(this);
QGroupBox* fileFrame = new QGroupBox(tr("File"), this);
m_levelNameEdit = new QLineEdit(this);
m_levelNameEdit = new LevelNameLineEdit(this);
// set the start frame 10 if the option in preferences
// "Show ABC Appendix to the Frame Number in Xsheet Cell" is active.
// (frame 10 is displayed as "1" with this option)
@ -524,11 +554,6 @@ PencilTestPopup::PencilTestPopup()
m_fileTypeCombo->setCurrentIndex(0);
fileFrame->setObjectName("CleanupSettingsFrame");
// Exclude all character which cannot fit in a filepath (Win).
// Dots are also prohibited since they are internally managed by Toonz.
QRegExp rx("[^\\\\/:?*.\"<>|]+");
m_levelNameEdit->setValidator(new QRegExpValidator(rx, this));
m_levelNameEdit->setObjectName("LargeSizedText");
m_frameNumberEdit->setObjectName("LargeSizedText");
nextLevelButton->setFixedSize(24, 24);
nextLevelButton->setArrowType(Qt::RightArrow);
@ -739,6 +764,8 @@ PencilTestPopup::PencilTestPopup()
this, SLOT(onResolutionComboActivated(const QString&)));
ret = ret && connect(m_fileFormatOptionButton, SIGNAL(pressed()), this,
SLOT(onFileFormatOptionButtonPressed()));
ret = ret && connect(m_levelNameEdit, SIGNAL(levelNameEdited()), this,
SLOT(onLevelNameEdited()));
ret = ret &&
connect(nextLevelButton, SIGNAL(pressed()), this, SLOT(onNextName()));
ret = ret && connect(m_colorTypeCombo, SIGNAL(currentIndexChanged(int)), this,
@ -764,14 +791,27 @@ PencilTestPopup::PencilTestPopup()
assert(ret);
refreshCameraList();
int startupCamIndex = m_cameraListCombo->findText(
QString::fromStdString(CamCapCameraName.getValue()));
if (startupCamIndex > 0) {
m_cameraListCombo->setCurrentIndex(startupCamIndex);
onCameraListComboActivated(startupCamIndex);
}
onNextName();
}
//-----------------------------------------------------------------------------
PencilTestPopup::~PencilTestPopup() {
if (m_currentCamera && m_currentCamera->state() == QCamera::ActiveState)
m_currentCamera->stop();
if (m_currentCamera) {
if (m_currentCamera->state() == QCamera::ActiveState)
m_currentCamera->stop();
if (m_currentCamera->state() == QCamera::LoadedState)
m_currentCamera->unload();
delete m_currentCamera;
}
// remove the cache image, if it exists
TFilePath fp(m_cacheImagePath);
if (TFileStatus(fp).doesExist()) TSystem::deleteFile(fp);
@ -790,27 +830,48 @@ void PencilTestPopup::refreshCameraList() {
}
int maxTextLength = 0;
int defaultIndex;
// add non-connected state as default
m_cameraListCombo->addItem(tr("- Select camera -"));
for (int c = 0; c < cameras.size(); c++) {
QString camDesc = cameras.at(c).description();
m_cameraListCombo->addItem(camDesc);
maxTextLength = std::max(maxTextLength, fontMetrics().width(camDesc));
if (cameras.at(c).deviceName() == QCameraInfo::defaultCamera().deviceName())
defaultIndex = c;
}
m_cameraListCombo->setMaximumWidth(maxTextLength + 25);
m_cameraListCombo->setEnabled(true);
m_cameraListCombo->setCurrentIndex(defaultIndex);
onCameraListComboActivated(defaultIndex);
m_cameraListCombo->setCurrentIndex(0);
}
//-----------------------------------------------------------------------------
void PencilTestPopup::onCameraListComboActivated(int index) {
void PencilTestPopup::onCameraListComboActivated(int comboIndex) {
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
if (cameras.size() != m_cameraListCombo->count()) return;
if (cameras.size() != m_cameraListCombo->count() - 1) return;
// if selected the non-connected state, then disconnect the current camera
if (comboIndex == 0) {
m_cameraViewfinder->setCamera(NULL);
if (m_cameraImageCapture) {
disconnect(m_cameraImageCapture,
SIGNAL(imageCaptured(int, const QImage&)), this,
SLOT(onImageCaptured(int, const QImage&)));
delete m_cameraImageCapture;
m_cameraImageCapture = NULL;
}
if (m_currentCamera) {
if (m_currentCamera->state() == QCamera::ActiveState)
m_currentCamera->stop();
if (m_currentCamera->state() == QCamera::LoadedState)
m_currentCamera->unload();
}
m_deviceName = QString();
m_cameraViewfinder->setImage(QImage());
// update env
CamCapCameraName = "";
return;
}
int index = comboIndex - 1;
// in case the camera is not changed (just click the combobox)
if (cameras.at(index).deviceName() == m_deviceName) return;
@ -850,11 +911,13 @@ void PencilTestPopup::onCameraListComboActivated(int index) {
settings.setResolution(sizes.last());
m_currentCamera->setViewfinderSettings(settings);
QImageEncoderSettings imageEncoderSettings;
imageEncoderSettings.setCodec("PNG");
imageEncoderSettings.setCodec("image/jpeg");
imageEncoderSettings.setQuality(QMultimedia::NormalQuality);
imageEncoderSettings.setResolution(sizes.last());
m_cameraImageCapture->setEncodingSettings(imageEncoderSettings);
}
m_cameraViewfinder->setCamera(m_currentCamera);
m_cameraViewfinder->updateSize();
// deleting old camera
if (oldCamera) {
@ -864,6 +927,9 @@ void PencilTestPopup::onCameraListComboActivated(int index) {
// start new camera
m_currentCamera->start();
m_cameraViewfinder->setImage(QImage());
// update env
CamCapCameraName = m_cameraListCombo->itemText(comboIndex).toStdString();
}
//-----------------------------------------------------------------------------
@ -886,6 +952,7 @@ void PencilTestPopup::onResolutionComboActivated(const QString& itemText) {
imageEncoderSettings.setQuality(QMultimedia::NormalQuality);
imageEncoderSettings.setResolution(newResolution);
m_cameraImageCapture->setEncodingSettings(imageEncoderSettings);
m_cameraViewfinder->updateSize();
// reset white bg
m_whiteBGImg = QImage();
@ -909,6 +976,17 @@ void PencilTestPopup::onFileFormatOptionButtonPressed() {
//-----------------------------------------------------------------------------
void PencilTestPopup::onLevelNameEdited() {
// set the start frame 10 if the option in preferences
// "Show ABC Appendix to the Frame Number in Xsheet Cell" is active.
// (frame 10 is displayed as "1" with this option)
int startFrame =
Preferences::instance()->isShowFrameNumberWithLettersEnabled() ? 10 : 1;
m_frameNumberEdit->setValue(startFrame);
}
//-----------------------------------------------------------------------------
void PencilTestPopup::onNextName() {
const std::auto_ptr<NameBuilder> nameBuilder(NameBuilder::getBuilder(L""));
@ -956,6 +1034,7 @@ void PencilTestPopup::onColorTypeComboChanged(int index) {
//-----------------------------------------------------------------------------
void PencilTestPopup::onImageCaptured(int id, const QImage& image) {
if (!m_cameraViewfinder) return;
// capture the white BG
if (m_captureWhiteBGCue) {
m_whiteBGImg = image.copy();
@ -1018,6 +1097,14 @@ void PencilTestPopup::showEvent(QShowEvent* event) {
// then release the shortcut key temporary while the popup opens
QAction* action = CommandManager::instance()->getActionFromShortcut("Return");
if (action) action->setShortcut(QKeySequence(""));
// reload camera
if (m_currentCamera) {
if (m_currentCamera->state() == QCamera::UnloadedState)
m_currentCamera->load();
if (m_currentCamera->state() == QCamera::LoadedState)
m_currentCamera->start();
}
}
//-----------------------------------------------------------------------------
@ -1034,6 +1121,14 @@ void PencilTestPopup::hideEvent(QHideEvent* event) {
m_captureButton->setChecked(false);
onCaptureButtonClicked(false);
}
// release camera
if (m_currentCamera) {
if (m_currentCamera->state() == QCamera::ActiveState)
m_currentCamera->stop();
if (m_currentCamera->state() == QCamera::LoadedState)
m_currentCamera->unload();
}
}
//-----------------------------------------------------------------------------
@ -1213,7 +1308,7 @@ bool PencilTestPopup::importImage(QImage& image) {
/* if the level does not exist in the scene cast */
else {
/* if the file does exist, load it first */
if (TFileStatus(actualLevelFp).doesExist()) {
if (TSystem::doesExistFileOrLevel(actualLevelFp)) {
level = scene->loadLevel(actualLevelFp);
if (!level) {
error(tr("Failed to load %1.").arg(toQString(actualLevelFp)));
@ -1229,6 +1324,15 @@ bool PencilTestPopup::importImage(QImage& image) {
"The captured image size does not match with the existing level."));
return false;
}
/* confirm overwrite */
QString question =
tr("File %1 does exist.\nDo you want to overwrite it?")
.arg(toQString(actualLevelFp.withFrame(frameNumber)));
int ret = DVGui::MsgBox(question, QObject::tr("Overwrite"),
QObject::tr("Cancel"));
if (ret == 0 || ret == 2) return false;
}
/* if the file does not exist, then create a new level */
else {
@ -1267,29 +1371,28 @@ bool PencilTestPopup::importImage(QImage& image) {
int col = app->getCurrentColumn()->getColumnIndex();
/* try to find the vacant cell */
int tmpRow = row;
bool isFoundEmptyCell = false;
int tmpRow = row;
while (1) {
if (xsh->getCell(tmpRow, col).isEmpty()) {
isFoundEmptyCell = true;
/* if the same cell is already in the column, then just replace the content
* and do not set a new cell */
if (xsh->getCell(tmpRow, col) == TXshCell(sl, fid)) break;
/* in case setting the same level as the the current column */
else if (xsh->getCell(tmpRow, col).isEmpty()) {
xsh->setCell(tmpRow, col, TXshCell(sl, fid));
break;
}
/* in case the level is different from the current column, then insert a new
column */
else if (xsh->getCell(tmpRow, col).m_level->getSimpleLevel() != sl) {
col += 1;
xsh->insertColumn(col);
xsh->setCell(row, col, TXshCell(sl, fid));
app->getCurrentColumn()->setColumnIndex(col);
break;
}
if (xsh->getCell(tmpRow, col).m_level->getSimpleLevel() != sl) break;
tmpRow++;
}
/* in case setting the same level as the the current column */
if (isFoundEmptyCell) {
xsh->setCell(tmpRow, col, TXshCell(sl, fid));
}
/* in case the level is different from the current column, then insert a new
column */
else {
col += 1;
xsh->insertColumn(col);
xsh->setCell(row, col, TXshCell(sl, fid));
app->getCurrentColumn()->setColumnIndex(col);
}
/* notify */
app->getCurrentScene()->notifySceneChanged();
app->getCurrentScene()->notifyCastChange();

View file

@ -61,6 +61,8 @@ public:
repaint();
}
void updateSize();
protected:
void paintEvent(QPaintEvent* event);
void resizeEvent(QResizeEvent* event);
@ -99,6 +101,25 @@ protected:
void showEvent(QShowEvent* event) override { updateValidator(); }
};
//=============================================================================
class LevelNameLineEdit : public QLineEdit {
Q_OBJECT
QString m_textOnFocusIn;
public:
LevelNameLineEdit(QWidget* parent = 0);
protected:
void focusInEvent(QFocusEvent* e);
protected slots:
void onEditingFinished();
signals:
void levelNameEdited();
};
//=============================================================================
// PencilTestPopup
//-----------------------------------------------------------------------------
@ -113,7 +134,7 @@ class PencilTestPopup : public DVGui::Dialog {
QComboBox *m_cameraListCombo, *m_resolutionCombo, *m_fileTypeCombo,
*m_colorTypeCombo;
QLineEdit* m_levelNameEdit;
LevelNameLineEdit* m_levelNameEdit;
QCheckBox *m_upsideDownCB, *m_onionSkinCB, *m_saveOnCaptureCB, *m_timerCB;
QPushButton *m_fileFormatOptionButton, *m_captureWhiteBGButton,
*m_captureButton;
@ -150,6 +171,7 @@ protected slots:
void onCameraListComboActivated(int index);
void onResolutionComboActivated(const QString&);
void onFileFormatOptionButtonPressed();
void onLevelNameEdited();
void onNextName();
void onColorTypeComboChanged(int index);
void onImageCaptured(int, const QImage&);