/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the demonstration applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "QCameraControllerWidget.h" //#include /***************************************************************************** * QCameraControllerWidget */ QCameraControllerWidget::QCameraControllerWidget(QWidget *parent) : QWidget(parent) { setWindowTitle("QCameraControllerWidget"); // Opitimizations for screen update and drawing qwidget setAutoFillBackground(false); // Prevent to screensaver to activate // m_systemScreenSaver = new QSystemScreenSaver(this); // m_systemScreenSaver->setScreenSaverInhibit(); m_myVideoSurface = 0; pictureCaptured = false; showViewFinder = false; m_focusing = false; // Black background QPalette palette = this->palette(); palette.setColor(QPalette::Background, Qt::black); setPalette(palette); // Main widget & layout // QWidget* mainWidget = new QWidget(this); setPalette(palette); QHBoxLayout* hboxl = new QHBoxLayout; hboxl->setSpacing(0); hboxl->setMargin(0); // UI stack m_stackedWidget = new QStackedWidget(); m_stackedWidget->setPalette(palette); // First widget to stack m_videoWidget = new QWidget(); m_videoWidget->setPalette(palette); m_stackedWidget->addWidget(m_videoWidget); // Second widget to stack QWidget* secondWidget = new QWidget(this); secondWidget->setPalette(palette); m_stackedWidget->addWidget(secondWidget); m_stackedWidget->setCurrentIndex(0); // Buttons QSize iconSize(80, 80); QVBoxLayout* vboxl = new QVBoxLayout; vboxl->setSpacing(0); vboxl->setMargin(0); zoomIn = new Button(this); QObject::connect(zoomIn, SIGNAL(pressed()), this, SLOT(onZoomIn())); QPixmap p = QPixmap(":/icons/zoomIn"); zoomIn->setPixmap(p.scaled(iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)); vboxl->addWidget(zoomIn); vboxl->setAlignment(zoomIn,Qt::AlignTop | Qt::AlignHCenter); zoomOut = new Button(this); QObject::connect(zoomOut, SIGNAL(pressed()), this, SLOT(onZoomOut())); p = QPixmap(":/icons/zoomOut"); zoomOut->setPixmap(p.scaled(iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)); vboxl->addWidget(zoomOut); vboxl->setAlignment(zoomOut, Qt::AlignBottom | Qt::AlignHCenter); //hboxl->addLayout(vboxl); hboxl->addWidget(m_stackedWidget); hboxl->addLayout(vboxl); setLayout(hboxl); // Enable camera after 1s, so that the application is started // and widget is created to landscape orientation QTimer::singleShot(1000,this,SLOT(enableCamera())); } QCameraControllerWidget::~QCameraControllerWidget() { if (m_myVideoSurface) m_myVideoSurface->stop(); m_camera->stop(); delete m_stackedWidget; delete m_stillImageCapture; delete m_camera; } void QCameraControllerWidget::enableCamera() { m_camera = new QCamera(); m_camera->setCaptureMode(QCamera::CaptureStillImage); connect(m_camera, SIGNAL(error(QCamera::Error)), this, SLOT(error(QCamera::Error))); connect(m_camera, SIGNAL(lockStatusChanged(QCamera::LockStatus,QCamera::LockChangeReason)), this, SLOT(lockStatusChanged(QCamera::LockStatus,QCamera::LockChangeReason))); connect(m_camera, SIGNAL(stateChanged( QCamera::State) ), this, SLOT(onStateChanged(QCamera::State))); // Own video output drawing that shows camera view finder pictures //! [0] QMediaService* ms = m_camera->service(); QVideoRendererControl* vrc = ms->requestControl(); m_myVideoSurface = new MyVideoSurface(this,this,this); vrc->setSurface(m_myVideoSurface); connect(m_myVideoSurface, SIGNAL(imageCaptured(QImage)), this, SLOT(redirectImageSignalFromVideoFinder(QImage))); //! [0] // Image capturer m_stillImageCapture = new QCameraImageCapture(m_camera); connect(m_stillImageCapture, SIGNAL(imageCaptured(int,QImage)), this, SLOT(onImageCaptured(int,QImage))); // Start camera if (m_camera->state() == QCamera::ActiveState) { m_camera->stop(); } m_videoWidget->show(); m_camera->start(); showViewFinder = true; cameraFocus = m_camera->focus(); // cameraFocus->setFocusMode(QCameraFocus::ContinuousFocus); // cameraFocus->setFocusPointMode(QCameraFocus::FocusPointAuto); } void QCameraControllerWidget::mousePressEvent(QMouseEvent *event) { QWidget::mousePressEvent(event); if (pictureCaptured) { // Starting view finder pictureCaptured = false; m_stackedWidget->setCurrentIndex(0); if (m_myVideoSurface) { showViewFinder = true; } } } void QCameraControllerWidget::searchAndLock() { m_focusing = false; m_focusMessage.clear(); if (pictureCaptured) { // Starting view finder again pictureCaptured = false; m_stackedWidget->setCurrentIndex(0); if (m_myVideoSurface) { showViewFinder = true; } } else { // Search and lock picture (=focus) if (m_camera->supportedLocks() & QCamera::LockFocus) { m_focusing = true; m_focusMessage = "Focusing..."; m_camera->searchAndLock(QCamera::LockFocus); } else { // No focus functionality, take picture right away captureImage(); } } } void QCameraControllerWidget::lockStatusChanged(QCamera::LockStatus status, QCamera::LockChangeReason reason) { if (status == QCamera::Locked) { if (reason == QCamera::LockAcquired) { // Focus locked m_focusMessage.clear(); m_focusing = false; // Capture new image captureImage(); // Unlock camera m_camera->unlock(); } else { if (m_focusing) m_focusMessage = "No focus, try again"; } } else if (status == QCamera::Unlocked && m_focusing) { m_focusMessage = "No focus, try again"; } } void QCameraControllerWidget::captureImage() { if (pictureCaptured) { // Starting view finder again pictureCaptured = false; m_stackedWidget->setCurrentIndex(0); showViewFinder = true; } else { // Capturing image showViewFinder = false; // Get picture location where to store captured images QString path(QDesktopServices::storageLocation(QDesktopServices::PicturesLocation)); QDir dir(path); // Get next filename QStringList files = dir.entryList(QStringList() << "camera_*.jpg"); int lastImage = 0; foreach ( QString fileName, files ) { int imgNumber = fileName.mid(7, fileName.size() - 11).toInt(); lastImage = qMax(lastImage, imgNumber); } // Capture image if (m_stillImageCapture->isReadyForCapture()) { m_imageName = QString("camera_%1.jpg").arg(lastImage+1); m_stillImageCapture->capture(m_imageName); } } } void QCameraControllerWidget::onImageCaptured(int id, const QImage &preview) { m_stillImageCapture->cancelCapture(); showViewFinder = false; m_focusing = false; // Image captured, show it to the user m_stackedWidget->setCurrentIndex(1); // Get picture location QString path(QDesktopServices::storageLocation(QDesktopServices::PicturesLocation)); m_imageName.prepend(path + "/"); m_capturedImage = preview; // Set suitable size to the image QSize s = m_videoWidget->size(); s = s - QSize(20, 20); m_capturedImage = m_capturedImage.scaled(s, Qt::KeepAspectRatio, Qt::SmoothTransformation); emit imageCaptured(preview); pictureCaptured = true; update(); } void QCameraControllerWidget::error(QCamera::Error e) { switch (e) { case QCamera::NoError: { break; } case QCamera::CameraError: { QMessageBox::warning(this, "QCameraControllerWidget", "General Camera error"); break; } case QCamera::InvalidRequestError: { QMessageBox::warning(this, "QCameraControllerWidget", "Camera invalid request error"); break; } case QCamera::ServiceMissingError: { QMessageBox::warning(this, "QCameraControllerWidget", "Camera service missing error"); break; } case QCamera::NotSupportedFeatureError : { QMessageBox::warning(this, "QCameraControllerWidget", "Camera not supported error"); break; } }; } void QCameraControllerWidget::updateVideo() { if (showViewFinder) { repaint(); } } void QCameraControllerWidget::paintEvent(QPaintEvent *event) { //QMainWindow::paintEvent(event); QPainter painter(this); QRect r = this->rect(); QFont font = painter.font(); font.setPixelSize(20); painter.setFont(font); painter.setPen(Qt::white); if (showViewFinder && m_myVideoSurface && m_myVideoSurface->isActive()) { // Show view finder m_myVideoSurface->paint(&painter); // Paint focus message if (!m_focusMessage.isEmpty()) painter.drawText(r, Qt::AlignCenter, m_focusMessage); } else { // Draw black painter.fillRect(event->rect(), palette().background()); // Show captured image // if (pictureCaptured) { // // Paint captured image // QPoint centerPic((qAbs(r.size().width() - m_capturedImage.size().width())) / 2, (qAbs( // r.size().height() - m_capturedImage.size().height())) / 2); // painter.drawImage(centerPic, m_capturedImage); // // Paint filename // // painter.drawText(r, Qt::AlignBottom | Qt::AlignCenter, m_imageName); // } } } void QCameraControllerWidget::redirectImageSignalFromVideoFinder(QImage image) { emit imageCaptured(image); } void QCameraControllerWidget::onZoomIn() { qreal optical = cameraFocus->opticalZoom(); qreal digital = cameraFocus->digitalZoom(); if(optical == cameraFocus->maximumOpticalZoom()) cameraFocus->zoomTo(optical, digital + 0.1); else cameraFocus->zoomTo(optical + 0.1, 1.0); } void QCameraControllerWidget::onZoomOut() { qreal optical = cameraFocus->opticalZoom(); qreal digital = cameraFocus->digitalZoom(); if(optical == cameraFocus->maximumOpticalZoom() && digital != 0.0) { if(digital - 0.1 >= 1) cameraFocus->zoomTo(optical, digital - 0.1); else cameraFocus->zoomTo(optical, 1.0); } else { if(optical - 0.1 >= 1) cameraFocus->zoomTo(optical - 0.1, 1.0); else cameraFocus->zoomTo(1.0, 1.0); } } void QCameraControllerWidget::onStateChanged(QCamera::State state) { if(state == QCamera::ActiveState) { // cameraFocus->setFocusMode(QCameraFocus::AutoFocus); // cameraFocus->setFocusPointMode(QCameraFocus::FocusPointAuto); } }