author | mickeyl <mickeyl> | 2003-04-06 14:38:18 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-04-06 14:38:18 (UTC) |
commit | 0b985ce87d6ce6d4110a50d5be48831d34794cd2 (patch) (side-by-side diff) | |
tree | da19d8dc2cd2b37d15220783940652e8e91f3843 | |
parent | 91d65a97c956963a24f418fadd7cd69f6a52f5d5 (diff) | |
download | opie-0b985ce87d6ce6d4110a50d5be48831d34794cd2.zip opie-0b985ce87d6ce6d4110a50d5be48831d34794cd2.tar.gz opie-0b985ce87d6ce6d4110a50d5be48831d34794cd2.tar.bz2 |
- add realtime preview widget with zoom control
The camera driver is damn slow. For a 240x160x16 image, it takes ~100ms. That gives approx. 10fps which is too slow for doing video. :(
-rw-r--r-- | noncore/multimedia/camera/.cvsignore | 4 | ||||
-rw-r--r-- | noncore/multimedia/camera/camera.pro | 4 | ||||
-rw-r--r-- | noncore/multimedia/camera/mainwindow.cpp | 40 | ||||
-rw-r--r-- | noncore/multimedia/camera/mainwindow.h | 12 | ||||
-rw-r--r-- | noncore/multimedia/camera/mainwindowbase.ui | 246 | ||||
-rw-r--r-- | noncore/multimedia/camera/previewwidget.cpp | 45 | ||||
-rw-r--r-- | noncore/multimedia/camera/previewwidget.h | 39 | ||||
-rw-r--r-- | noncore/multimedia/camera/zcameraio.cpp | 58 |
8 files changed, 397 insertions, 51 deletions
diff --git a/noncore/multimedia/camera/.cvsignore b/noncore/multimedia/camera/.cvsignore index 6d678c6..d89e3af 100644 --- a/noncore/multimedia/camera/.cvsignore +++ b/noncore/multimedia/camera/.cvsignore @@ -1 +1,5 @@ config.in +mainwindowbase.h +mainwindowbase.cpp +Makefile + diff --git a/noncore/multimedia/camera/camera.pro b/noncore/multimedia/camera/camera.pro index e937807..2d1faa3 100644 --- a/noncore/multimedia/camera/camera.pro +++ b/noncore/multimedia/camera/camera.pro @@ -1,21 +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 -INTERFACES = +INTERFACES = mainwindowbase.ui TARGET = opiecam include ( $(OPIEDIR)/include.pro ) diff --git a/noncore/multimedia/camera/mainwindow.cpp b/noncore/multimedia/camera/mainwindow.cpp index 4218232..8578bce 100644 --- a/noncore/multimedia/camera/mainwindow.cpp +++ b/noncore/multimedia/camera/mainwindow.cpp @@ -1,64 +1,60 @@ /********************************************************************** ** 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 "mainwindowbase.h" #include "zcameraio.h" #include <qvbox.h> +#include <qcombobox.h> #include <qpushbutton.h> #include <qlabel.h> - #include <qdirectpainter_qws.h> - #include <qpe/resource.h> #include <opie/ofiledialog.h> +#include <assert.h> + CameraMainWindow::CameraMainWindow( QWidget * parent, const char * name, WFlags f ) :QMainWindow( parent, name, f ) { - QVBox* v = new QVBox( this ); - l = new QLabel( v ); - l->setFixedSize( QSize( 240, 160 ) ); - QPushButton* p = new QPushButton( "Snapshot", v ); - connect( p, SIGNAL( clicked() ), this, SLOT( clickedSnapShot() ) ); - v->show(); - l->show(); - p->show(); - setCentralWidget( v ); + mw = new MainWindowBase( this, "main widget" ); + ZCameraIO::instance()->setCaptureFrame( 240, 160, 256 ); + setCentralWidget( mw ); + mw->show(); + connect( mw->zoom, SIGNAL( activated( int ) ), this, SLOT( changeZoom(int) ) ); }; CameraMainWindow::~CameraMainWindow() { } -void CameraMainWindow::clickedSnapShot() +void CameraMainWindow::changeZoom( int zoom ) { - QDirectPainter fb( l ); - ZCameraIO::instance()->snapshot( fb.frameBuffer() ); - - /* - QImage i; - QPixmap p; - if ( ZCameraIO::instance()->snapshot( &i ) ) + int z; + switch ( zoom ) { - p.convertFromImage( i ); - l->setPixmap( p ); + 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 ); } diff --git a/noncore/multimedia/camera/mainwindow.h b/noncore/multimedia/camera/mainwindow.h index 521107b..7ccdcf8 100644 --- a/noncore/multimedia/camera/mainwindow.h +++ b/noncore/multimedia/camera/mainwindow.h @@ -1,42 +1,46 @@ /********************************************************************** ** 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 QIconSet; class QToolButton; class QLabel; +class MainWindowBase; class CameraMainWindow: public QMainWindow { Q_OBJECT public: CameraMainWindow( QWidget * parent = 0, const char * name = "mainwindow", WFlags f = 0 ); virtual ~CameraMainWindow(); - protected: - public slots: - void clickedSnapShot(); + void changeZoom( int ); + + protected: private: - QLabel* l; + MainWindowBase* mw; }; #endif diff --git a/noncore/multimedia/camera/mainwindowbase.ui b/noncore/multimedia/camera/mainwindowbase.ui new file mode 100644 index 0000000..8da884a --- a/dev/null +++ b/noncore/multimedia/camera/mainwindowbase.ui @@ -0,0 +1,246 @@ +<!DOCTYPE UI><UI> +<class>MainWindowBase</class> +<widget> + <class>QWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>MainWindowBase</cstring> + </property> + <property stdset="1"> + <name>geometry</name> + <rect> + <x>0</x> + <y>0</y> + <width>242</width> + <height>329</height> + </rect> + </property> + <property stdset="1"> + <name>caption</name> + <string>Form1</string> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <grid> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>2</number> + </property> + <widget row="1" column="0" > + <class>QLayoutWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Layout1</cstring> + </property> + <hbox> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>TextLabel1</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Reso:</string> + </property> + </widget> + <widget> + <class>QComboBox</class> + <item> + <property> + <name>text</name> + <string>240x160</string> + </property> + </item> + <item> + <property> + <name>text</name> + <string>480x320</string> + </property> + </item> + <property stdset="1"> + <name>name</name> + <cstring>resolution</cstring> + </property> + </widget> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>TextLabel2</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Zoom:</string> + </property> + </widget> + <widget> + <class>QComboBox</class> + <item> + <property> + <name>text</name> + <string>Half</string> + </property> + </item> + <item> + <property> + <name>text</name> + <string>Full</string> + </property> + </item> + <item> + <property> + <name>text</name> + <string>Double</string> + </property> + </item> + <property stdset="1"> + <name>name</name> + <cstring>zoom</cstring> + </property> + </widget> + </hbox> + </widget> + <widget row="2" column="0" > + <class>QLayoutWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Layout2</cstring> + </property> + <hbox> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <spacer> + <property> + <name>name</name> + <cstring>Spacer1</cstring> + </property> + <property stdset="1"> + <name>orientation</name> + <enum>Horizontal</enum> + </property> + <property stdset="1"> + <name>sizeType</name> + <enum>Expanding</enum> + </property> + <property> + <name>sizeHint</name> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget> + <class>QPushButton</class> + <property stdset="1"> + <name>name</name> + <cstring>PushButton1</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Take Photo</string> + </property> + <property stdset="1"> + <name>default</name> + <bool>true</bool> + </property> + </widget> + <spacer> + <property> + <name>name</name> + <cstring>Spacer2</cstring> + </property> + <property stdset="1"> + <name>orientation</name> + <enum>Horizontal</enum> + </property> + <property stdset="1"> + <name>sizeType</name> + <enum>Expanding</enum> + </property> + <property> + <name>sizeHint</name> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <spacer row="3" column="0" > + <property> + <name>name</name> + <cstring>Spacer3</cstring> + </property> + <property stdset="1"> + <name>orientation</name> + <enum>Vertical</enum> + </property> + <property stdset="1"> + <name>sizeType</name> + <enum>Expanding</enum> + </property> + <property> + <name>sizeHint</name> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget row="0" column="0" > + <class>PreviewWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>preview</cstring> + </property> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>PreviewWidget</class> + <header location="local">previewwidget.h</header> + <sizehint> + <width>240</width> + <height>160</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>0</hordata> + <verdata>0</verdata> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image> + <name>image0</name> + <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1ddec44f503c0ae2a154410f53d0ed20e2bf6bdb656dd6861dd23d9a66591b0587fd1654235ebded6f0edcd53e419d87ae7b1f4f9b8f906d0bfe012317426a70b07bdc2f3ec77f8ed6b89559061a0343d06a124cc105596482585094bc0ae599b04646c9018926491b2205e140c485cace25755c175d0a967b622ff900b8cc9c7d29af594ea722d589167f813aa852ba07d94b9dce296e883fe7bb163f23896753</data> + </image> +</images> +</UI> diff --git a/noncore/multimedia/camera/previewwidget.cpp b/noncore/multimedia/camera/previewwidget.cpp new file mode 100644 index 0000000..bb84c00 --- a/dev/null +++ b/noncore/multimedia/camera/previewwidget.cpp @@ -0,0 +1,45 @@ +/********************************************************************** +** 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" + +PreviewWidget::PreviewWidget( QWidget * parent, const char * name, WFlags f ) + :QLabel( parent, name, f ) +{ + setFixedSize( QSize( 240, 160 ) ); + setBackgroundMode( NoBackground ); + + startTimer( 150 ); +}; + + +PreviewWidget::~PreviewWidget() +{ +} + + +void PreviewWidget::timerEvent( QTimerEvent* ) +{ + //QDirectPainter fb( this ); + //ZCameraIO::instance()->snapshot( fb.frameBuffer() ); + + if ( ZCameraIO::instance()->snapshot( &i ) ) + { + p.convertFromImage( i ); + setPixmap( p ); + } +} + diff --git a/noncore/multimedia/camera/previewwidget.h b/noncore/multimedia/camera/previewwidget.h new file mode 100644 index 0000000..c031d95 --- a/dev/null +++ b/noncore/multimedia/camera/previewwidget.h @@ -0,0 +1,39 @@ +/********************************************************************** +** 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 PREVIEWWIDGET_H +#define PREVIEWWIDGET_H + +#include <qlabel.h> +#include <qimage.h> +#include <qpixmap.h> + +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* ); + + private: + QPixmap p; + QImage i; +}; + +#endif diff --git a/noncore/multimedia/camera/zcameraio.cpp b/noncore/multimedia/camera/zcameraio.cpp index 7343dca..56b2e13 100644 --- a/noncore/multimedia/camera/zcameraio.cpp +++ b/noncore/multimedia/camera/zcameraio.cpp @@ -1,206 +1,216 @@ /********************************************************************** ** 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 "zcameraio.h" #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <qimage.h> +#include <qdatetime.h> #include <opie2/odebug.h> +#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( "/dev/sharp_zdc", O_RDWR ); + _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 { setReadMode( STATUS ); } } ZCameraIO::~ZCameraIO() { if ( _driver != -1 ) + { + setReadMode( 0 ); ::close( _driver ); + } } inline bool ZCameraIO::isOpen() const { return _driver != -1; } inline bool ZCameraIO::isShutterPressed() { return _status[0] == 'S'; clearShutterLatch(); } inline bool ZCameraIO::isFinderReversed() const { return _status[1] == 'M'; } inline bool ZCameraIO::isCapturing() const { return _status[2] == 'C'; } inline bool ZCameraIO::isAvailable() const { return _status[3] == 'A'; } bool ZCameraIO::setCaptureFrame( int width, int height, int zoom, bool rot ) { 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; + _height = height; _zoom = zoom; _rot = rot; _readlen = 2 * _width * _height; // camera is fixed @ 16 bits per pixel return true; } return false; } void ZCameraIO::setReadMode( int mode ) { - char b[4]; + char b[10]; sprintf( b, "M=%d", mode ); write( b, mode <= 9 ? 3 : 4 ); if ( mode & 1 ) // STATUS bit is set read( _status, 4 ); } void ZCameraIO::clearShutterLatch() { char b = 'B'; write( &b, 1 ); } bool ZCameraIO::read( char* b, int len ) { + #ifndef NO_TIMING + QTime t; + t.start(); + #endif int rlen = ::read( _driver, b, len ); - odebug << "read " << rlen << " from driver." << oendl; + #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; } bool ZCameraIO::snapshot( QImage* image ) { - /* - + setReadMode( IMAGE | XFLIP | YFLIP ); char buf[76800]; - - write( _driver, "M=13", 4 ); - write( _driver, "R=240,160,256,480", 17 ); - write( _driver, "M=12", 4 ); - - int result = read( _driver, &buf, sizeof buf ); - - return result == sizeof buf; - - */ - - unsigned char buf[76800]; - unsigned char* bp = buf; + char* bp = buf; unsigned char* p; - int fd = open( "/tmp/cam", O_RDONLY ); - if ( ::read( fd, buf, sizeof buf ) != sizeof buf ) - owarn << "Couldn't read image from /dev/sharp_zdc" << oendl; + read( bp, _readlen ); image->create( 240, 160, 16 ); for ( int i = 0; i < 160; ++i ) { p = image->scanLine( i ); for ( int j = 0; j < 240; j++ ) { *p = *bp; p++; bp++; *p = *bp; p++; bp++; } } return true; } -bool ZCameraIO::snapshot( uchar* buf ) +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, buf, 76800 ) != 76800 ) + if ( ::read( fd, (char*) buf, 76800 ) != 76800 ) owarn << "Couldn't read image from /dev/sharp_zdc" << oendl; + // TESTCODE */ + return true; } |