-rw-r--r-- | noncore/multimedia/camera/camera.pro | 2 | ||||
-rw-r--r-- | noncore/multimedia/camera/mainwindow.cpp | 144 | ||||
-rw-r--r-- | noncore/multimedia/camera/mainwindow.h | 22 | ||||
-rw-r--r-- | noncore/multimedia/camera/previewwidget.cpp | 16 | ||||
-rw-r--r-- | noncore/multimedia/camera/previewwidget.h | 4 | ||||
-rw-r--r-- | noncore/multimedia/camera/zcameraio.cpp | 44 | ||||
-rw-r--r-- | noncore/multimedia/camera/zcameraio.h | 22 |
7 files changed, 235 insertions, 19 deletions
diff --git a/noncore/multimedia/camera/camera.pro b/noncore/multimedia/camera/camera.pro index 16da0c9..ffd5f37 100644 --- a/noncore/multimedia/camera/camera.pro +++ b/noncore/multimedia/camera/camera.pro @@ -1,23 +1,23 @@ MOC_DIR = ./moc OBJECTS_DIR = ./obj DESTDIR = $(OPIEDIR)/bin TEMPLATE = app CONFIG = qt warn_on debug HEADERS = zcameraio.h \ previewwidget.h \ mainwindow.h SOURCES = zcameraio.cpp \ previewwidget.cpp \ mainwindow.cpp \ main.cpp INCLUDEPATH += $(OPIEDIR)/include DEPENDPATH += $(OPIEDIR)/include -LIBS += -lqpe -lopiecore2 +LIBS += -lqpe -lopie -lopiecore2 INTERFACES = TARGET = opiecam include ( $(OPIEDIR)/include.pro ) diff --git a/noncore/multimedia/camera/mainwindow.cpp b/noncore/multimedia/camera/mainwindow.cpp index 34ebe9e..8e89039 100644 --- a/noncore/multimedia/camera/mainwindow.cpp +++ b/noncore/multimedia/camera/mainwindow.cpp @@ -1,121 +1,253 @@ /********************************************************************** ** Copyright (C) 2002 Michael 'Mickey' Lauer. All rights reserved. ** ** This file is part of Opie Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** **********************************************************************/ #include "mainwindow.h" #include "previewwidget.h" #include "zcameraio.h" +#include <qapplication.h> +#include <qaction.h> #include <qvbox.h> #include <qcombobox.h> #include <qcursor.h> #include <qdatastream.h> +#include <qfile.h> +#include <qimage.h> #include <qlabel.h> #include <qpopupmenu.h> #include <qpushbutton.h> #include <qmessagebox.h> #include <qdirectpainter_qws.h> +#include <qpe/global.h> #include <qpe/resource.h> #include <qpe/qcopenvelope_qws.h> #include <opie/ofiledialog.h> +#include <opie/odevice.h> +using namespace Opie; #include <opie2/odebug.h> #include <assert.h> CameraMainWindow::CameraMainWindow( QWidget * parent, const char * name, WFlags f ) - :QMainWindow( parent, name, f ) + :QMainWindow( parent, name, f ), _pics( 0 ) { + #ifdef QT_NO_DEBUG if ( !ZCameraIO::instance()->isOpen() ) { QVBox* v = new QVBox( this ); v->setMargin( 10 ); QLabel* l1 = new QLabel( v ); l1->setPixmap( Resource::loadPixmap( "camera/error" ) ); QLabel* l2 = new QLabel( v ); l2->setText( "<b>Sorry. could not detect your camera :-(</b><p>" "* Is the sharpzdc_cs module loaded ?<br>" "* Is /dev/sharpzdc read/writable ?<p>" ); connect( new QPushButton( "Exit", v ), SIGNAL( clicked() ), this, SLOT( close() ) ); setCentralWidget( v ); return; } + #endif + + init(); _rotation = 270; //TODO: grab these from the actual settings preview = new PreviewWidget( this, "camera preview widget" ); //setCentralWidget( preview ); <--- don't do this! preview->resize( QSize( 240, 288 ) ); preview->show(); // construct a System Channel to receive setRotation messages _sysChannel = new QCopChannel( "QPE/System", this ); connect( _sysChannel, SIGNAL( received( const QCString&, const QByteArray& ) ), this, SLOT( systemMessage( const QCString&, const QByteArray& ) ) ); connect( preview, SIGNAL( contextMenuRequested() ), this, SLOT( showContextMenu() ) ); + + connect( ZCameraIO::instance(), SIGNAL( shutterClicked() ), this, SLOT( shutterClicked() ) ); }; CameraMainWindow::~CameraMainWindow() { } +void CameraMainWindow::init() +{ + // TODO: Save this stuff in config + quality = 50; + zoom = 1; + captureX = 640; + captureY = 480; + captureFormat = "JPEG"; + + resog = new QActionGroup( 0, "reso", true ); + resog->setToggleAction( true ); + new QAction( " 64 x 48", 0, 0, resog, 0, true ); + new QAction( "128 x 96", 0, 0, resog, 0, true ); + new QAction( "192 x 144", 0, 0, resog, 0, true ); + new QAction( "256 x 192", 0, 0, resog, 0, true ); + new QAction( "320 x 240", 0, 0, resog, 0, true ); + new QAction( "384 x 288", 0, 0, resog, 0, true ); + new QAction( "448 x 336", 0, 0, resog, 0, true ); + new QAction( "512 x 384", 0, 0, resog, 0, true ); + new QAction( "576 x 432", 0, 0, resog, 0, true ); + ( new QAction( "640 x 480", 0, 0, resog, 0, true ) )->setOn( true ); + + qualityg = new QActionGroup( 0, "quality", true ); + qualityg->setToggleAction( true ); + new QAction( " 0 (minimal)", 0, 0, qualityg, 0, true ); + new QAction( " 25 (low)", 0, 0, qualityg, 0, true ); + ( new QAction( " 50 (good)", 0, 0, qualityg, 0, true ) )->setOn( true ); + new QAction( " 75 (better)", 0, 0, qualityg, 0, true ); + new QAction( "100 (best)", 0, 0, qualityg, 0, true ); + + zoomg = new QActionGroup( 0, "zoom", true ); + zoomg->setToggleAction( true ); + ( new QAction( "x 1", 0, 0, zoomg, 0, true ) )->setOn( true ); + new QAction( "x 2", 0, 0, zoomg, 0, true ); + + outputg = new QActionGroup( 0, "output", true ); + outputg->setToggleAction( true ); + ( new QAction( "JPEG", 0, 0, outputg, 0, true ) )->setOn( true ); + new QAction( "PNG", 0, 0, outputg, 0, true ); + new QAction( "BMP", 0, 0, outputg, 0, true ); + + connect( resog, SIGNAL( selected(QAction*) ), this, SLOT( resoMenuItemClicked(QAction*) ) ); + connect( qualityg, SIGNAL( selected(QAction*) ), this, SLOT( qualityMenuItemClicked(QAction*) ) ); + connect( zoomg, SIGNAL( selected(QAction*) ), this, SLOT( zoomMenuItemClicked(QAction*) ) ); + connect( outputg, SIGNAL( selected(QAction*) ), this, SLOT( outputMenuItemClicked(QAction*) ) ); +} + + void CameraMainWindow::systemMessage( const QCString& msg, const QByteArray& data ) { QDataStream stream( data, IO_ReadOnly ); odebug << "received system message: " << msg << oendl; if ( msg == "setCurrentRotation(int)" ) { stream >> _rotation; odebug << "received setCurrentRotation(" << _rotation << ")" << oendl; switch ( _rotation ) { case 270: preview->resize( QSize( 240, 288 ) ); break; case 180: preview->resize( QSize( 320, 208 ) ); break; default: QMessageBox::warning( this, "opie-camera", "This rotation is not supported.\n" "Supported are 180° and 270°" ); } } } void CameraMainWindow::changeZoom( int zoom ) { int z; switch ( zoom ) { case 0: z = 128; break; case 1: z = 256; break; case 2: z = 512; break; default: assert( 0 ); break; } ZCameraIO::instance()->setCaptureFrame( 240, 160, z ); } - void CameraMainWindow::showContextMenu() { + QPopupMenu reso; + reso.setCheckable( true ); + resog->addTo( &reso ); + + QPopupMenu quality; + quality.setCheckable( true ); + qualityg->addTo( &quality ); + + QPopupMenu zoom; + zoom.setCheckable( true ); + zoomg->addTo( &zoom ); + + QPopupMenu output; + output.setCheckable( true ); + outputg->addTo( &output ); + QPopupMenu m( this ); - m.insertItem( "Item 1" ); - m.insertItem( "Item 1" ); - m.insertItem( "Item 1" ); - m.insertItem( "Item 1" ); + m.insertItem( "&Resolution", &reso ); + m.insertItem( "&Zoom", &zoom ); + m.insertItem( "&Quality", &quality ); + m.insertItem( "&Output As", &output ); m.exec( QCursor::pos() ); } + +void CameraMainWindow::resoMenuItemClicked( QAction* a ) +{ + captureX = a->text().left(3).toInt(); + captureY = a->text().right(3).toInt(); + odebug << "Capture Resolution now: " << captureX << ", " << captureY << oendl; +} + + +void CameraMainWindow::qualityMenuItemClicked( QAction* a ) +{ + quality = a->text().left(3).toInt(); + odebug << "Quality now: " << quality << oendl; +} + + +void CameraMainWindow::zoomMenuItemClicked( QAction* a ) +{ + zoom = QString( a->text()[2] ).toInt(); + odebug << "Zoom now: " << zoom << oendl; + ZCameraIO::instance()->setZoom( zoom ); +} + + +void CameraMainWindow::outputMenuItemClicked( QAction* a ) +{ + captureFormat = a->text(); + odebug << "Output format now: " << captureFormat << oendl; +} + + +void CameraMainWindow::shutterClicked() +{ + Global::statusMessage( "CAPTURING..." ); + qApp->processEvents(); + + odebug << "Shutter has been pressed" << oendl; + ODevice::inst()->touchSound(); + QString name; + name.sprintf( "/tmp/image-%d_%d_%d_q%d.%s", _pics++, captureX, captureY, quality, (const char*) captureFormat.lower() ); + QImage i; + ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, &i ); + QImage im = i.convertDepth( 32 ); + bool result = im.save( name, captureFormat, quality ); + if ( !result ) + { + oerr << "imageio-Problem while writing." << oendl; + Global::statusMessage( "Error!" ); + } + else + { + odebug << captureFormat << "-image has been successfully captured" << oendl; + Global::statusMessage( "Ok." ); + } +} + diff --git a/noncore/multimedia/camera/mainwindow.h b/noncore/multimedia/camera/mainwindow.h index df66204..7a12452 100644 --- a/noncore/multimedia/camera/mainwindow.h +++ b/noncore/multimedia/camera/mainwindow.h @@ -1,53 +1,73 @@ /********************************************************************** ** Copyright (C) 2003 Michael 'Mickey' Lauer. All rights reserved. ** ** This file is part of Opie Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** **********************************************************************/ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <qmainwindow.h> #include <qdatetime.h> #include <qimage.h> #include <qpixmap.h> +class QAction; +class QActionGroup; class QIconSet; class QToolButton; class QLabel; class MainWindowBase; class QCopChannel; class PreviewWidget; class CameraMainWindow: public QMainWindow { Q_OBJECT public: CameraMainWindow( QWidget * parent = 0, const char * name = "mainwindow", WFlags f = 0 ); virtual ~CameraMainWindow(); public slots: void changeZoom( int ); void systemMessage( const QCString&, const QByteArray& ); - void showContextMenu(); + void resoMenuItemClicked( QAction* ); + void qualityMenuItemClicked( QAction* ); + void zoomMenuItemClicked( QAction* ); + void outputMenuItemClicked( QAction* ); + void shutterClicked(); protected: + void init(); private: PreviewWidget* preview; int _rotation; QCopChannel* _sysChannel; + + QActionGroup* resog; + QActionGroup* qualityg; + QActionGroup* zoomg; + QActionGroup* outputg; + + int quality; + int zoom; + int captureX; + int captureY; + QString captureFormat; + + int _pics; }; #endif diff --git a/noncore/multimedia/camera/previewwidget.cpp b/noncore/multimedia/camera/previewwidget.cpp index cdeacf6..f87dcc9 100644 --- a/noncore/multimedia/camera/previewwidget.cpp +++ b/noncore/multimedia/camera/previewwidget.cpp @@ -1,64 +1,74 @@ /********************************************************************** ** Copyright (C) 2002 Michael 'Mickey' Lauer. All rights reserved. ** ** This file is part of Opie Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** **********************************************************************/ #include "previewwidget.h" #include "zcameraio.h" #include <opie2/odebug.h> +#include <assert.h> + PreviewWidget::PreviewWidget( QWidget * parent, const char * name, WFlags f ) :QLabel( parent, name, f ) { #ifndef QT_NO_DEBUG setBackgroundColor( QColor( 255, 0, 0 ) ); #else setBackgroundMode( NoBackground ); #endif - - startTimer( 150 ); - //startTimer( 2000 ); + #ifndef QT_NO_DEBUG + if ( ZCameraIO::instance()->isOpen() ) startTimer( 1500 ); + #else + if ( ZCameraIO::instance()->isOpen() ) startTimer( 200 ); + #endif }; PreviewWidget::~PreviewWidget() { } void PreviewWidget::resizeEvent( QResizeEvent* e ) { QLabel::resizeEvent( e ); int w = e->size().width(); int h = e->size().height(); ZCameraIO::instance()->setCaptureFrame( e->size().width(), e->size().height(), 256, w < h ); } void PreviewWidget::timerEvent( QTimerEvent* ) { //QDirectPainter fb( this ); //ZCameraIO::instance()->snapshot( fb.frameBuffer() ); if ( ZCameraIO::instance()->snapshot( &i ) ) { p.convertFromImage( i ); setPixmap( p ); } } + +void PreviewWidget::mousePressEvent( QMouseEvent* ) +{ + emit contextMenuRequested(); +} + diff --git a/noncore/multimedia/camera/previewwidget.h b/noncore/multimedia/camera/previewwidget.h index 6b64768..dada301 100644 --- a/noncore/multimedia/camera/previewwidget.h +++ b/noncore/multimedia/camera/previewwidget.h @@ -5,39 +5,43 @@ ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** **********************************************************************/ #ifndef PREVIEWWIDGET_H #define PREVIEWWIDGET_H #include <qlabel.h> #include <qimage.h> #include <qpixmap.h> class QTimerEvent; class QResizeEvent; class PreviewWidget: public QLabel { Q_OBJECT public: PreviewWidget( QWidget * parent = 0, const char * name = 0, WFlags f = 0 ); virtual ~PreviewWidget(); protected: virtual void timerEvent( QTimerEvent* ); virtual void resizeEvent( QResizeEvent* ); + virtual void mousePressEvent( QMouseEvent* ); + + signals: + void contextMenuRequested(); private: QPixmap p; QImage i; }; #endif diff --git a/noncore/multimedia/camera/zcameraio.cpp b/noncore/multimedia/camera/zcameraio.cpp index b37ae8c..9af0c25 100644 --- a/noncore/multimedia/camera/zcameraio.cpp +++ b/noncore/multimedia/camera/zcameraio.cpp @@ -31,142 +31,161 @@ #define SHARPZDC "/dev/sharp_zdc" ZCameraIO* ZCameraIO::_instance = 0; ZCameraIO* ZCameraIO::instance() { if ( !ZCameraIO::_instance ) { odebug << "Creating ZCameraIO::_instance" << oendl; ZCameraIO::_instance = new ZCameraIO(); } return ZCameraIO::_instance; } ZCameraIO::ZCameraIO() :_height( 0 ), _width( 0 ), _zoom( 0 ), _rot( 0 ), _readlen( 0 ) { _driver = ::open( SHARPZDC, O_RDWR ); if ( _driver == -1 ) oerr << "Can't open camera driver: " << strerror(errno) << oendl; else init(); } void ZCameraIO::init() { if ( ZCameraIO::_instance ) ofatal << "Don't create more than one ZCameraIO instances." << oendl; else { + _timer = new QTime(); setReadMode( STATUS ); } } ZCameraIO::~ZCameraIO() { if ( _driver != -1 ) { setReadMode( 0 ); ::close( _driver ); } } bool ZCameraIO::isOpen() const { return _driver != -1; } bool ZCameraIO::isShutterPressed() { - return _status[0] == 'S'; - clearShutterLatch(); + if ( _timer->elapsed() < 1000 ) //TODO: make this customizable? + { + clearShutterLatch(); + return false; + } + if ( _status[0] == 'S' ) + { + _timer->restart(); + clearShutterLatch(); + return true; + } + else return false; } bool ZCameraIO::isFinderReversed() const { return _status[1] == 'M'; } bool ZCameraIO::isCapturing() const { return _status[2] == 'C'; } bool ZCameraIO::isAvailable() const { return _status[3] == 'A'; } bool ZCameraIO::setCaptureFrame( int width, int height, int zoom, bool rot ) { odebug << "setCaptureFrame( " << width << ", " << height << ", " << zoom << ", " << rot << " )" << oendl; char b[100]; sprintf( b, "%c=%d,%d,%d,%d", rot ? 'R':'S', width, height, zoom, width*2 ); if ( write( b ) ) { _width = width; _height = height; _zoom = zoom; _rot = rot; _readlen = 2 * _width * _height; // camera is fixed @ 16 bits per pixel return true; } return false; } +bool ZCameraIO::setZoom( int zoom ) +{ + return setCaptureFrame( _width, _height, zoom*256, _rot ); +} + + void ZCameraIO::setReadMode( int mode ) { char b[10]; sprintf( b, "M=%d", mode ); write( b, mode <= 9 ? 3 : 4 ); - if ( mode & 1 ) // STATUS bit is set + if ( mode & STATUS ) // STATUS bit is set + { read( _status, 4 ); + if ( isShutterPressed() ) emit shutterClicked(); + } } void ZCameraIO::clearShutterLatch() { - char b = 'B'; - write( &b, 1 ); + write( "B", 1 ); } bool ZCameraIO::read( char* b, int len ) { #ifndef NO_TIMING QTime t; t.start(); #endif int rlen = ::read( _driver, b, len ); #ifndef NO_TIMING int time = t.elapsed(); #else int time = -1; #endif if ( rlen ) odebug << "read " << rlen << " ('" << b[0] << b[1] << b[2] << b[3] << "') [" << time << " ms] from driver." << oendl; else odebug << "read nothing from driver." << oendl; return rlen == len; } bool ZCameraIO::write( char* buf, int len ) { if ( !len ) len = strlen( buf ); odebug << "writing '" << buf << "' to driver." << oendl; return ::write( _driver, buf, len ) == len; } @@ -183,48 +202,63 @@ bool ZCameraIO::snapshot( QImage* image ) { setReadMode( IMAGE | isFinderReversed() ? XFLIP | YFLIP : 0 ); } else // Landscape { setReadMode( IMAGE | XFLIP | YFLIP ); //isFinderReversed() ? 0 : XFLIP ); } char buf[_readlen]; char* bp = buf; unsigned char* p; read( bp, _readlen ); image->create( _width, _height, 16 ); for ( int i = 0; i < _height; ++i ) { p = image->scanLine( i ); for ( int j = 0; j < _width; j++ ) { *p = *bp; p++; bp++; *p = *bp; p++; bp++; } } return true; } + bool ZCameraIO::snapshot( unsigned char* buf ) { setReadMode( IMAGE | XFLIP | YFLIP ); read( (char*) buf, _readlen ); /* //TESTCODE int fd = open( "/tmp/cam", O_RDONLY ); if ( ::read( fd, (char*) buf, 76800 ) != 76800 ) owarn << "Couldn't read image from /dev/sharp_zdc" << oendl; // TESTCODE */ return true; } + +void ZCameraIO::captureFrame( int w, int h, int zoom, QImage* image ) +{ + int pw = _width; + int ph = _height; + if ( _rot ) + setCaptureFrame( h, w, zoom*256, true ); + else + setCaptureFrame( w, h, zoom*256, false ); + snapshot( image ); + setCaptureFrame( pw, ph, _zoom, _rot ); +} + + diff --git a/noncore/multimedia/camera/zcameraio.h b/noncore/multimedia/camera/zcameraio.h index 9d4b1d7..edce143 100644 --- a/noncore/multimedia/camera/zcameraio.h +++ b/noncore/multimedia/camera/zcameraio.h @@ -1,65 +1,81 @@ /********************************************************************** ** Copyright (C) 2003 Michael 'Mickey' Lauer. All rights reserved. ** ** This file is part of Opie Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** **********************************************************************/ #ifndef ZCAMERAIO_H #define ZCAMERAIO_H +#include <qobject.h> + class QImage; +class QTime; -class ZCameraIO +class ZCameraIO : public QObject { + Q_OBJECT + public: virtual ~ZCameraIO(); enum ReadMode { IMAGE = 0, STATUS = 1, FASTER = 0, BETTER = 2, XNOFLIP = 0, XFLIP = 4, YNOFLIP = 0, YFLIP = 8 }; + // low level interface + bool setCaptureFrame( int w, int h, int zoom = 256, bool rot = true ); + bool setZoom( int zoom = 0 ); void setReadMode( int = IMAGE | XFLIP | YFLIP ); bool isShutterPressed(); // not const, because it calls clearShutterLatch bool isAvailable() const; bool isCapturing() const; bool isFinderReversed() const; - bool isOpen() const; - bool snapshot( QImage* ); bool snapshot( unsigned char* ); + bool snapshot( QImage* ); + + // high level interface + bool isOpen() const; static ZCameraIO* instance(); + void captureFrame( int w, int h, int zoom, QImage* image ); protected: ZCameraIO(); void clearShutterLatch(); void init(); bool read( char*, int ); bool write( char*, int = 0 ); + signals: + void shutterClicked(); + private: int _driver; char _status[4]; static ZCameraIO* _instance; int _height; int _width; int _zoom; bool _rot; int _readlen; + + QTime* _timer; }; #endif |