-rw-r--r-- | noncore/multimedia/camera/gui/.cvsignore | 1 | ||||
-rw-r--r-- | noncore/multimedia/camera/gui/gui.pro | 21 | ||||
-rw-r--r-- | noncore/multimedia/camera/gui/main.cpp | 28 | ||||
-rw-r--r-- | noncore/multimedia/camera/gui/mainwindow.cpp | 692 | ||||
-rw-r--r-- | noncore/multimedia/camera/gui/mainwindow.h | 107 | ||||
-rw-r--r-- | noncore/multimedia/camera/gui/previewwidget.cpp | 88 | ||||
-rw-r--r-- | noncore/multimedia/camera/gui/previewwidget.h | 50 | ||||
-rw-r--r-- | noncore/multimedia/camera/lib/.cvsignore | 1 |
8 files changed, 988 insertions, 0 deletions
diff --git a/noncore/multimedia/camera/gui/.cvsignore b/noncore/multimedia/camera/gui/.cvsignore index 737c5b2..2a3a7a8 100644 --- a/noncore/multimedia/camera/gui/.cvsignore +++ b/noncore/multimedia/camera/gui/.cvsignore | |||
@@ -1 +1,2 @@ | |||
1 | *.pro | ||
1 | moc | 2 | moc |
diff --git a/noncore/multimedia/camera/gui/gui.pro b/noncore/multimedia/camera/gui/gui.pro new file mode 100644 index 0000000..3d76ad4 --- a/dev/null +++ b/noncore/multimedia/camera/gui/gui.pro | |||
@@ -0,0 +1,21 @@ | |||
1 | MOC_DIR = ./moc | ||
2 | OBJECTS_DIR = ./obj | ||
3 | DESTDIR = $(OPIEDIR)/bin | ||
4 | TEMPLATE = app | ||
5 | CONFIG = qt warn_on debug | ||
6 | |||
7 | HEADERS = previewwidget.h \ | ||
8 | mainwindow.h | ||
9 | |||
10 | SOURCES = previewwidget.cpp \ | ||
11 | mainwindow.cpp \ | ||
12 | main.cpp | ||
13 | |||
14 | INCLUDEPATH += $(OPIEDIR)/include ../lib | ||
15 | DEPENDPATH += $(OPIEDIR)/include ../lib | ||
16 | LIBS += -lqpe -lopie -lopiecore2 -lopiecam | ||
17 | INTERFACES = | ||
18 | TARGET = opiecam | ||
19 | |||
20 | include ( $(OPIEDIR)/include.pro ) | ||
21 | |||
diff --git a/noncore/multimedia/camera/gui/main.cpp b/noncore/multimedia/camera/gui/main.cpp new file mode 100644 index 0000000..f25475c --- a/dev/null +++ b/noncore/multimedia/camera/gui/main.cpp | |||
@@ -0,0 +1,28 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2003 Michael 'Mickey' Lauer. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Opie Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | **********************************************************************/ | ||
15 | |||
16 | #include "mainwindow.h" | ||
17 | #include <opie2/oapplication.h> | ||
18 | |||
19 | int main( int argc, char **argv ) | ||
20 | { | ||
21 | OApplication a( argc, argv, "Opie-Camera" ); | ||
22 | CameraMainWindow* w = new CameraMainWindow(); | ||
23 | a.showMainWidget( w ); | ||
24 | a.exec(); | ||
25 | delete w; | ||
26 | return 0; | ||
27 | } | ||
28 | |||
diff --git a/noncore/multimedia/camera/gui/mainwindow.cpp b/noncore/multimedia/camera/gui/mainwindow.cpp new file mode 100644 index 0000000..49c7cbf --- a/dev/null +++ b/noncore/multimedia/camera/gui/mainwindow.cpp | |||
@@ -0,0 +1,692 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2002 Michael 'Mickey' Lauer. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Opie Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | **********************************************************************/ | ||
15 | |||
16 | #include "mainwindow.h" | ||
17 | #include "previewwidget.h" | ||
18 | #include "zcameraio.h" | ||
19 | #include "imageio.h" | ||
20 | #include "avi.h" | ||
21 | |||
22 | #include <qapplication.h> | ||
23 | #include <qaction.h> | ||
24 | #include <qvbox.h> | ||
25 | #include <qcombobox.h> | ||
26 | #include <qcursor.h> | ||
27 | #include <qdatastream.h> | ||
28 | #include <qdir.h> | ||
29 | #include <qfile.h> | ||
30 | #include <qimage.h> | ||
31 | #include <qlabel.h> | ||
32 | #include <qlineedit.h> | ||
33 | #include <qpopupmenu.h> | ||
34 | #include <qprogressbar.h> | ||
35 | #include <qpushbutton.h> | ||
36 | #include <qmessagebox.h> | ||
37 | #include <qlayout.h> | ||
38 | #include <qdirectpainter_qws.h> | ||
39 | #include <qpe/global.h> | ||
40 | #include <qpe/resource.h> | ||
41 | #include <qpe/qcopenvelope_qws.h> | ||
42 | #include <opie/ofiledialog.h> | ||
43 | #include <opie/odevice.h> | ||
44 | using namespace Opie; | ||
45 | #include <opie2/odebug.h> | ||
46 | |||
47 | #include <assert.h> | ||
48 | #include <sys/types.h> | ||
49 | #include <sys/stat.h> | ||
50 | #include <fcntl.h> | ||
51 | #include <string.h> | ||
52 | #include <errno.h> | ||
53 | #include <unistd.h> | ||
54 | |||
55 | #define CAPTUREFILE "/tmp/capture.dat" | ||
56 | #define OUTPUTFILE "/tmp/output.avi" | ||
57 | |||
58 | #define OUTPUT_TO_CUSTOM 250 | ||
59 | #define OUTPUT_TO_DOCFOLDER 251 | ||
60 | |||
61 | CameraMainWindow::CameraMainWindow( QWidget * parent, const char * name, WFlags f ) | ||
62 | :QMainWindow( parent, name, f ), | ||
63 | _rotation( 270 ), // FIXME: get this from current settings (ODevice?) | ||
64 | _capturing( false ), | ||
65 | _pics( 1 ), _videos( 1 ) | ||
66 | { | ||
67 | #ifdef QT_NO_DEBUG | ||
68 | if ( !ZCameraIO::instance()->isOpen() ) | ||
69 | { | ||
70 | QVBox* v = new QVBox( this ); | ||
71 | v->setMargin( 10 ); | ||
72 | QLabel* l1 = new QLabel( v ); | ||
73 | l1->setPixmap( Resource::loadPixmap( "camera/error" ) ); | ||
74 | QLabel* l2 = new QLabel( v ); | ||
75 | l2->setText( "<b>Sorry. could not detect your camera :-(</b><p>" | ||
76 | "* Is the sharpzdc_cs module loaded ?<br>" | ||
77 | "* Is /dev/sharpzdc read/writable ?<p>" ); | ||
78 | connect( new QPushButton( "Exit", v ), SIGNAL( clicked() ), this, SLOT( close() ) ); | ||
79 | setCentralWidget( v ); | ||
80 | return; | ||
81 | } | ||
82 | #endif | ||
83 | |||
84 | init(); | ||
85 | |||
86 | _rotation = 270; //TODO: grab these from the actual settings | ||
87 | |||
88 | preview = new PreviewWidget( this, "camera preview widget" ); | ||
89 | //setCentralWidget( preview ); <--- don't do this! | ||
90 | preview->resize( QSize( 240, 288 ) ); | ||
91 | preview->show(); | ||
92 | |||
93 | // construct a System Channel to receive setRotation messages | ||
94 | _sysChannel = new QCopChannel( "QPE/System", this ); | ||
95 | connect( _sysChannel, SIGNAL( received( const QCString&, const QByteArray& ) ), | ||
96 | this, SLOT( systemMessage( const QCString&, const QByteArray& ) ) ); | ||
97 | |||
98 | connect( preview, SIGNAL( contextMenuRequested() ), this, SLOT( showContextMenu() ) ); | ||
99 | |||
100 | connect( ZCameraIO::instance(), SIGNAL( shutterClicked() ), this, SLOT( shutterClicked() ) ); | ||
101 | |||
102 | updateCaption(); | ||
103 | |||
104 | }; | ||
105 | |||
106 | |||
107 | CameraMainWindow::~CameraMainWindow() | ||
108 | { | ||
109 | } | ||
110 | |||
111 | |||
112 | void CameraMainWindow::init() | ||
113 | { | ||
114 | // TODO: Save this stuff in config | ||
115 | flip = 'A'; // auto | ||
116 | quality = 50; | ||
117 | zoom = 1; | ||
118 | captureX = 480; | ||
119 | captureY = 640; | ||
120 | captureFormat = "JPEG"; | ||
121 | outputTo = "Documents Folder"; | ||
122 | prefix = "Untitled"; | ||
123 | appendSettings = true; | ||
124 | |||
125 | resog = new QActionGroup( 0, "reso", true ); | ||
126 | resog->setToggleAction( true ); | ||
127 | new QAction( " 64 x 48", 0, 0, resog, 0, true ); | ||
128 | new QAction( "128 x 96", 0, 0, resog, 0, true ); | ||
129 | new QAction( "192 x 144", 0, 0, resog, 0, true ); | ||
130 | new QAction( "256 x 192", 0, 0, resog, 0, true ); | ||
131 | new QAction( "320 x 240", 0, 0, resog, 0, true ); | ||
132 | new QAction( "384 x 288", 0, 0, resog, 0, true ); | ||
133 | new QAction( "448 x 336", 0, 0, resog, 0, true ); | ||
134 | new QAction( "512 x 384", 0, 0, resog, 0, true ); | ||
135 | new QAction( "576 x 432", 0, 0, resog, 0, true ); | ||
136 | ( new QAction( "640 x 480", 0, 0, resog, 0, true ) )->setOn( true ); | ||
137 | |||
138 | qualityg = new QActionGroup( 0, "quality", true ); | ||
139 | qualityg->setToggleAction( true ); | ||
140 | new QAction( " 0 (&minimal)", 0, 0, qualityg, 0, true ); | ||
141 | new QAction( " 25 (&low)", 0, 0, qualityg, 0, true ); | ||
142 | ( new QAction( " 50 (&good)", 0, 0, qualityg, 0, true ) )->setOn( true ); | ||
143 | new QAction( " 75 (&better)", 0, 0, qualityg, 0, true ); | ||
144 | new QAction( "100 (bes&t)", 0, 0, qualityg, 0, true ); | ||
145 | |||
146 | zoomg = new QActionGroup( 0, "zoom", true ); | ||
147 | zoomg->setToggleAction( true ); | ||
148 | ( new QAction( "x 1", 0, 0, zoomg, 0, true ) )->setOn( true ); | ||
149 | new QAction( "x 2", 0, 0, zoomg, 0, true ); | ||
150 | |||
151 | flipg = new QActionGroup( 0, "flip", true ); | ||
152 | flipg->setToggleAction( true ); | ||
153 | ( new QAction( "Auto (recommended)", 0, 0, flipg, 0, true ) )->setOn( true ); | ||
154 | new QAction( "0 (always off)", 0, 0, flipg, 0, true ); | ||
155 | new QAction( "X (always horizontal)", 0, 0, flipg, 0, true ); | ||
156 | new QAction( "Y (always vertical)", 0, 0, flipg, 0, true ); | ||
157 | new QAction( "* (always both)", 0, 0, flipg, 0, true ); | ||
158 | |||
159 | outputTog = new QActionGroup( 0, "output", true ); | ||
160 | outputTog->setToggleAction( true ); | ||
161 | new QAction( "/tmp/", 0, 0, outputTog, 0, true ); | ||
162 | new QAction( "/mnt/card/", 0, 0, outputTog, 0, true ); | ||
163 | new QAction( "/mnt/cf/", 0, 0, outputTog, 0, true ); | ||
164 | docfolder = new QAction( "Documents Folder", 0, 0, outputTog, 0, true ); | ||
165 | docfolder->setOn( true ); | ||
166 | custom = new QAction( "&Custom...", 0, 0, outputTog, 0, true ); | ||
167 | |||
168 | outputg = new QActionGroup( 0, "output", true ); | ||
169 | outputg->setToggleAction( true ); | ||
170 | ( new QAction( "JPEG", 0, 0, outputg, 0, true ) )->setOn( true ); | ||
171 | new QAction( "PNG", 0, 0, outputg, 0, true ); | ||
172 | new QAction( "BMP", 0, 0, outputg, 0, true ); | ||
173 | new QAction( "AVI", 0, 0, outputg, 0, true ); | ||
174 | |||
175 | connect( resog, SIGNAL( selected(QAction*) ), this, SLOT( resoMenuItemClicked(QAction*) ) ); | ||
176 | connect( qualityg, SIGNAL( selected(QAction*) ), this, SLOT( qualityMenuItemClicked(QAction*) ) ); | ||
177 | connect( zoomg, SIGNAL( selected(QAction*) ), this, SLOT( zoomMenuItemClicked(QAction*) ) ); | ||
178 | connect( flipg, SIGNAL( selected(QAction*) ), this, SLOT( flipMenuItemClicked(QAction*) ) ); | ||
179 | connect( outputTog, SIGNAL( selected(QAction*) ), this, SLOT( outputToMenuItemClicked(QAction*) ) ); | ||
180 | connect( outputg, SIGNAL( selected(QAction*) ), this, SLOT( outputMenuItemClicked(QAction*) ) ); | ||
181 | |||
182 | } | ||
183 | |||
184 | |||
185 | void CameraMainWindow::systemMessage( const QCString& msg, const QByteArray& data ) | ||
186 | { | ||
187 | int _newrotation; | ||
188 | |||
189 | QDataStream stream( data, IO_ReadOnly ); | ||
190 | odebug << "received system message: " << msg << oendl; | ||
191 | if ( msg == "setCurrentRotation(int)" ) | ||
192 | { | ||
193 | stream >> _newrotation; | ||
194 | odebug << "received setCurrentRotation(" << _newrotation << ")" << oendl; | ||
195 | |||
196 | switch ( _newrotation ) | ||
197 | { | ||
198 | case 270: preview->resize( QSize( 240, 288 ) ); break; | ||
199 | case 180: preview->resize( QSize( 320, 208 ) ); break; | ||
200 | default: QMessageBox::warning( this, "opie-camera", | ||
201 | "This rotation is not supported.\n" | ||
202 | "Supported are 180° and 270°" ); | ||
203 | } | ||
204 | |||
205 | if ( _newrotation != _rotation ) | ||
206 | { | ||
207 | int tmp = captureX; | ||
208 | captureX = captureY; | ||
209 | captureY = tmp; | ||
210 | _rotation = _newrotation; | ||
211 | } | ||
212 | |||
213 | updateCaption(); | ||
214 | |||
215 | } | ||
216 | } | ||
217 | |||
218 | |||
219 | void CameraMainWindow::changeZoom( int zoom ) | ||
220 | { | ||
221 | int z; | ||
222 | switch ( zoom ) | ||
223 | { | ||
224 | case 0: z = 128; break; | ||
225 | case 1: z = 256; break; | ||
226 | case 2: z = 512; break; | ||
227 | default: assert( 0 ); break; | ||
228 | } | ||
229 | |||
230 | ZCameraIO::instance()->setCaptureFrame( 240, 160, z ); | ||
231 | } | ||
232 | |||
233 | |||
234 | void CameraMainWindow::showContextMenu() | ||
235 | { | ||
236 | QPopupMenu reso; | ||
237 | reso.setCheckable( true ); | ||
238 | resog->addTo( &reso ); | ||
239 | |||
240 | QPopupMenu quality; | ||
241 | quality.setCheckable( true ); | ||
242 | qualityg->addTo( &quality ); | ||
243 | |||
244 | QPopupMenu flip; | ||
245 | flip.setCheckable( true ); | ||
246 | flipg->addTo( &flip ); | ||
247 | |||
248 | QPopupMenu zoom; | ||
249 | zoom.setCheckable( true ); | ||
250 | zoomg->addTo( &zoom ); | ||
251 | |||
252 | QPopupMenu prefix; | ||
253 | prefix.insertItem( "&Choose...", this, SLOT( prefixItemChoosen() ) ); | ||
254 | int id = prefix.insertItem( "&Append Settings", this, SLOT( appendSettingsChoosen() ) ); | ||
255 | prefix.setItemChecked( id, appendSettings ); | ||
256 | |||
257 | QPopupMenu outputTo; | ||
258 | outputTo.setCheckable( true ); | ||
259 | outputTog->addTo( &outputTo ); | ||
260 | |||
261 | QPopupMenu output; | ||
262 | output.setCheckable( true ); | ||
263 | outputg->addTo( &output ); | ||
264 | |||
265 | QPopupMenu m( this ); | ||
266 | m.insertItem( "&Resolution", &reso ); | ||
267 | m.insertItem( "&Zoom", &zoom ); | ||
268 | m.insertItem( "&Flip", &flip ); | ||
269 | m.insertItem( "&Quality", &quality ); | ||
270 | m.insertSeparator(); | ||
271 | m.insertItem( "&Prefix", &prefix ); | ||
272 | m.insertItem( "Output &To", &outputTo ); | ||
273 | m.insertItem( "&Output As", &output ); | ||
274 | |||
275 | #ifndef QT_NO_DEBUG | ||
276 | m.insertItem( "&Debug!", this, SLOT( doSomething() ) ); | ||
277 | #endif | ||
278 | |||
279 | m.exec( QCursor::pos() ); | ||
280 | } | ||
281 | |||
282 | |||
283 | void CameraMainWindow::resoMenuItemClicked( QAction* a ) | ||
284 | { | ||
285 | switch ( _rotation ) | ||
286 | { | ||
287 | case 270: | ||
288 | captureY = a->text().left(3).toInt(); | ||
289 | captureX = a->text().right(3).toInt(); | ||
290 | break; | ||
291 | case 180: | ||
292 | captureX = a->text().left(3).toInt(); | ||
293 | captureY = a->text().right(3).toInt(); | ||
294 | break; | ||
295 | default: QMessageBox::warning( this, "opie-camera", | ||
296 | "This rotation is not supported.\n" | ||
297 | "Supported are 180° and 270°" ); | ||
298 | } | ||
299 | odebug << "Capture Resolution now: " << captureX << ", " << captureY << oendl; | ||
300 | updateCaption(); | ||
301 | } | ||
302 | |||
303 | |||
304 | void CameraMainWindow::qualityMenuItemClicked( QAction* a ) | ||
305 | { | ||
306 | quality = a->text().left(3).toInt(); | ||
307 | odebug << "Quality now: " << quality << oendl; | ||
308 | updateCaption(); | ||
309 | } | ||
310 | |||
311 | |||
312 | void CameraMainWindow::zoomMenuItemClicked( QAction* a ) | ||
313 | { | ||
314 | zoom = QString( a->text().at(2) ).toInt(); | ||
315 | odebug << "Zoom now: " << zoom << oendl; | ||
316 | ZCameraIO::instance()->setZoom( zoom ); | ||
317 | updateCaption(); | ||
318 | } | ||
319 | |||
320 | |||
321 | void CameraMainWindow::flipMenuItemClicked( QAction* a ) | ||
322 | { | ||
323 | flip = QString( a->text().at(0) ); | ||
324 | odebug << "Flip now: " << flip << oendl; | ||
325 | if ( flip == "A" ) | ||
326 | ZCameraIO::instance()->setFlip( ZCameraIO::AUTOMATICFLIP ); | ||
327 | else if ( flip == "0" ) | ||
328 | ZCameraIO::instance()->setFlip( ZCameraIO::XNOFLIP | ZCameraIO::YNOFLIP ); | ||
329 | else if ( flip == "X" ) | ||
330 | ZCameraIO::instance()->setFlip( ZCameraIO::XFLIP ); | ||
331 | else if ( flip == "Y" ) | ||
332 | ZCameraIO::instance()->setFlip( ZCameraIO::YFLIP ); | ||
333 | else if ( flip == "*" ) | ||
334 | ZCameraIO::instance()->setFlip( ZCameraIO::XFLIP | ZCameraIO::YFLIP ); | ||
335 | |||
336 | updateCaption(); | ||
337 | } | ||
338 | |||
339 | |||
340 | void CameraMainWindow::outputToMenuItemClicked( QAction* a ) | ||
341 | { | ||
342 | if ( a->text() == "&Custom..." ) | ||
343 | { | ||
344 | QMap<QString, QStringList> map; | ||
345 | map.insert( tr("All"), QStringList() ); | ||
346 | QStringList text; | ||
347 | text << "text/*"; | ||
348 | map.insert(tr("Text"), text ); | ||
349 | text << "*"; | ||
350 | map.insert(tr("All"), text ); | ||
351 | |||
352 | QString str; | ||
353 | str = OFileDialog::getSaveFileName( 2, "/", QString::null, map ); | ||
354 | if ( str.isEmpty() || !QFileInfo(str).isDir() ) | ||
355 | { | ||
356 | docfolder->setOn( true ); | ||
357 | outputTo = "Documents Folder"; | ||
358 | } | ||
359 | else | ||
360 | { | ||
361 | outputTo = str; | ||
362 | } | ||
363 | } | ||
364 | else | ||
365 | { | ||
366 | outputTo = a->text(); | ||
367 | } | ||
368 | odebug << "Output to now: " << outputTo << oendl; | ||
369 | } | ||
370 | |||
371 | |||
372 | void CameraMainWindow::outputMenuItemClicked( QAction* a ) | ||
373 | { | ||
374 | captureFormat = a->text(); | ||
375 | odebug << "Output format now: " << captureFormat << oendl; | ||
376 | updateCaption(); | ||
377 | } | ||
378 | |||
379 | |||
380 | void CameraMainWindow::prefixItemChoosen() | ||
381 | { | ||
382 | QDialog* d = new QDialog( this, "dialog", true ); | ||
383 | d->setCaption( "Enter Prefix..." ); | ||
384 | QVBoxLayout* v = new QVBoxLayout( d ); | ||
385 | QLineEdit* le = new QLineEdit( prefix, d ); | ||
386 | v->addWidget( le ); | ||
387 | le->setFixedWidth( 150 ); //FIXME: 'tis a bit dirty | ||
388 | if ( d->exec() == QDialog::Accepted ) | ||
389 | prefix = le->text(); | ||
390 | odebug << "Prefix now: " << prefix << oendl; | ||
391 | } | ||
392 | |||
393 | |||
394 | void CameraMainWindow::appendSettingsChoosen() | ||
395 | { | ||
396 | appendSettings = !appendSettings; | ||
397 | odebug << "appendSettings now: " << appendSettings << oendl; | ||
398 | } | ||
399 | |||
400 | |||
401 | void CameraMainWindow::shutterClicked() | ||
402 | { | ||
403 | if ( captureFormat != "AVI" ) // capture one photo per shutterClick | ||
404 | { | ||
405 | Global::statusMessage( "CAPTURING..." ); | ||
406 | qApp->processEvents(); | ||
407 | |||
408 | odebug << "Shutter has been pressed" << oendl; | ||
409 | ODevice::inst()->touchSound(); | ||
410 | |||
411 | performCapture( captureFormat ); | ||
412 | } | ||
413 | else // capture video! start with one shutter click and stop with the next | ||
414 | { | ||
415 | !_capturing ? startVideoCapture() : stopVideoCapture(); | ||
416 | } | ||
417 | } | ||
418 | |||
419 | |||
420 | void CameraMainWindow::performCapture( const QString& format ) | ||
421 | { | ||
422 | QString name; | ||
423 | |||
424 | if ( outputTo == "Documents Folder" ) | ||
425 | { | ||
426 | name.sprintf( "%s/Documents/image/%s/", (const char*) QDir::homeDirPath(), (const char*) captureFormat.lower() ); | ||
427 | if ( !QDir( name ).exists() ) | ||
428 | { | ||
429 | odebug << "creating directory " << name << oendl; | ||
430 | QString msg = "mkdir -p " + name; | ||
431 | system( msg.latin1() ); | ||
432 | } | ||
433 | } | ||
434 | else | ||
435 | name = outputTo; | ||
436 | |||
437 | name.append( prefix ); | ||
438 | if ( appendSettings ) | ||
439 | { | ||
440 | name.append( QString().sprintf( "_%d_%d_q%d", captureX, captureY, quality ) ); | ||
441 | } | ||
442 | name.append( QString().sprintf( "-%d.%s", _pics++, (const char*) captureFormat.lower() ) ); | ||
443 | |||
444 | QImage i; | ||
445 | ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, &i ); | ||
446 | QImage im = i.convertDepth( 32 ); | ||
447 | bool result = im.save( name, format, quality ); | ||
448 | if ( !result ) | ||
449 | { | ||
450 | oerr << "imageio-Problem while writing." << oendl; | ||
451 | Global::statusMessage( "Error!" ); | ||
452 | } | ||
453 | else | ||
454 | { | ||
455 | odebug << captureFormat << "-image has been successfully captured" << oendl; | ||
456 | Global::statusMessage( "Ok." ); | ||
457 | } | ||
458 | } | ||
459 | |||
460 | |||
461 | void CameraMainWindow::startVideoCapture() | ||
462 | { | ||
463 | //ODevice::inst()->touchSound(); | ||
464 | ODevice::inst()->setLedState( Led_Mail, Led_BlinkSlow ); | ||
465 | |||
466 | _capturefd = ::open( CAPTUREFILE, O_WRONLY | O_CREAT | O_TRUNC ); | ||
467 | if ( _capturefd == -1 ) | ||
468 | { | ||
469 | owarn << "can't open capture file: " << strerror(errno) << oendl; | ||
470 | return; | ||
471 | } | ||
472 | |||
473 | _capturebuf = new unsigned char[captureX*captureY*2]; | ||
474 | _capturing = true; | ||
475 | _videopics = 0; | ||
476 | _framerate = 0; | ||
477 | updateCaption(); | ||
478 | _time.start(); | ||
479 | preview->setRefreshingRate( 1000 ); | ||
480 | startTimer( 100 ); // too fast but that is ok | ||
481 | } | ||
482 | |||
483 | |||
484 | void CameraMainWindow::timerEvent( QTimerEvent* ) | ||
485 | { | ||
486 | if ( !_capturing ) | ||
487 | { | ||
488 | odebug << "timer event in CameraMainWindow without capturing video ?" << oendl; | ||
489 | return; | ||
490 | } | ||
491 | |||
492 | odebug << "timer event during video - now capturing frame #" << _videopics+1 << oendl; | ||
493 | |||
494 | ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, _capturebuf ); | ||
495 | _videopics++; | ||
496 | ::write( _capturefd, _capturebuf, captureX*captureY*2 ); | ||
497 | setCaption( QString().sprintf( "Capturing %dx%d @ %.2f fps %d", | ||
498 | captureX, captureY, 1000.0 / (_time.elapsed()/_videopics), _videopics ) ); | ||
499 | } | ||
500 | |||
501 | |||
502 | void CameraMainWindow::stopVideoCapture() | ||
503 | { | ||
504 | killTimers(); | ||
505 | //ODevice::inst()->touchSound(); | ||
506 | ODevice::inst()->setLedState( Led_Mail, Led_Off ); | ||
507 | _capturing = false; | ||
508 | updateCaption(); | ||
509 | ::close( _capturefd ); | ||
510 | _framerate = 1000.0 / (_time.elapsed()/_videopics); | ||
511 | |||
512 | QString name; | ||
513 | if ( outputTo == "Documents Folder" ) | ||
514 | { | ||
515 | name.sprintf( "%s/Documents/video/%s/", (const char*) QDir::homeDirPath(), (const char*) captureFormat.lower() ); | ||
516 | if ( !QDir( name ).exists() ) | ||
517 | { | ||
518 | odebug << "creating directory " << name << oendl; | ||
519 | QString msg = "mkdir -p " + name; | ||
520 | system( msg.latin1() ); | ||
521 | } | ||
522 | } | ||
523 | else | ||
524 | name = outputTo; | ||
525 | |||
526 | name.append( "/" ); // sure is sure and safe is safe ;-) | ||
527 | name.append( prefix ); | ||
528 | if ( appendSettings ) | ||
529 | name.append( QString().sprintf( "_%d_%d_q%d_%dfps", captureX, captureY, quality, _framerate ) ); | ||
530 | name.append( QString().sprintf( "-%d.%s", _videos++, (const char*) captureFormat.lower() ) ); | ||
531 | postProcessVideo( CAPTUREFILE, name ); | ||
532 | |||
533 | #ifndef QT_NO_DEBUG | ||
534 | preview->setRefreshingRate( 1500 ); | ||
535 | #else | ||
536 | preview->setRefreshingRate( 200 ); | ||
537 | #endif | ||
538 | |||
539 | //delete[] _capturebuf; //FIXME: close memory leak | ||
540 | } | ||
541 | |||
542 | void CameraMainWindow::postProcessVideo( const QString& infile, const QString& outfile ) | ||
543 | { | ||
544 | odebug << "post processing " << infile << " --> " << outfile << oendl; | ||
545 | |||
546 | preview->setRefreshingRate( 0 ); | ||
547 | |||
548 | /* | ||
549 | unsigned char buf[153600]; | ||
550 | |||
551 | int fd = ::open( "/var/compile/opie/noncore/multimedia/camera/capture-320x240.dat", O_RDONLY ); | ||
552 | ::read( fd, &buf, 153600 ); | ||
553 | QImage i; | ||
554 | bufferToImage( 240, 320, (unsigned char*) &buf, &i ); | ||
555 | QPixmap p; | ||
556 | p.convertFromImage( i ); | ||
557 | preview->setPixmap( p ); | ||
558 | imageToFile( &i, "/tmp/tmpfile", "JPEG", 100 ); | ||
559 | return; | ||
560 | */ | ||
561 | |||
562 | QDialog* fr = new QDialog( this, "splash", false, QWidget::WStyle_StaysOnTop ); //, false, QWidget::WStyle_NoBorder | QWidget::WStyle_Customize ); | ||
563 | fr->setCaption( "Please wait..." ); | ||
564 | QVBoxLayout* box = new QVBoxLayout( fr, 2, 2 ); | ||
565 | QProgressBar* bar = new QProgressBar( fr ); | ||
566 | bar->setCenterIndicator( true ); | ||
567 | bar->setTotalSteps( _videopics-1 ); | ||
568 | QLabel* label = new QLabel( "Post processing frame bla/bla", fr ); | ||
569 | box->addWidget( bar ); | ||
570 | box->addWidget( label ); | ||
571 | fr->show(); | ||
572 | label->show(); | ||
573 | bar->show(); | ||
574 | fr->repaint(); | ||
575 | qApp->processEvents(); | ||
576 | |||
577 | // open files | ||
578 | |||
579 | int infd = ::open( (const char*) infile, O_RDONLY ); | ||
580 | if ( infd == -1 ) | ||
581 | { | ||
582 | owarn << "couldn't open capture file: " << strerror(errno) << oendl; | ||
583 | return; | ||
584 | } | ||
585 | |||
586 | int outfd = ::open( (const char*) outfile, O_CREAT | O_WRONLY | O_TRUNC, 0644 ); | ||
587 | if ( outfd == -1 ) | ||
588 | { | ||
589 | owarn << "couldn't open output file: " << strerror(errno) << oendl; | ||
590 | return; | ||
591 | } | ||
592 | |||
593 | int framesize = captureX*captureY*2; | ||
594 | |||
595 | unsigned char* inbuffer = new unsigned char[ framesize ]; | ||
596 | QImage image; | ||
597 | |||
598 | avi_start( outfd, _videopics ); // write preambel | ||
599 | |||
600 | // post process | ||
601 | |||
602 | for ( int i = 0; i < _videopics; ++i ) | ||
603 | { | ||
604 | odebug << "processing frame " << i << oendl; | ||
605 | |||
606 | // <gui> | ||
607 | label->setText( QString().sprintf( "Post processing frame %d / %d", i+1, _videopics ) ); | ||
608 | bar->setProgress( i ); | ||
609 | bar->repaint(); | ||
610 | qApp->processEvents(); | ||
611 | // </gui> | ||
612 | |||
613 | int read = ::read( infd, inbuffer, framesize ); | ||
614 | odebug << "read " << read << " bytes" << oendl; | ||
615 | bufferToImage( captureX, captureY, inbuffer, &image ); | ||
616 | |||
617 | QPixmap p; | ||
618 | p.convertFromImage( image ); | ||
619 | preview->setPixmap( p ); | ||
620 | preview->repaint(); | ||
621 | qApp->processEvents(); | ||
622 | |||
623 | #ifdef CAMERA_EXTRA_DEBUG | ||
624 | QString tmpfilename; | ||
625 | tmpfilename.sprintf( "/tmp/test/%04d.jpg", i ); | ||
626 | #else | ||
627 | QString tmpfilename( "/tmp/tempfile" ); | ||
628 | #endif | ||
629 | |||
630 | imageToFile( &image, tmpfilename, "JPEG", quality ); | ||
631 | |||
632 | QFile framefile( tmpfilename ); | ||
633 | if ( !framefile.open( IO_ReadOnly ) ) | ||
634 | { | ||
635 | oerr << "can't process file: %s" << strerror(errno) << oendl; | ||
636 | return; // TODO: clean up temp ressources | ||
637 | } | ||
638 | |||
639 | int filesize = framefile.size(); | ||
640 | odebug << "filesize for frame " << i << " = " << filesize << oendl; | ||
641 | |||
642 | unsigned char* tempbuffer = new unsigned char[ filesize ]; | ||
643 | framefile.readBlock( (char*) tempbuffer, filesize ); | ||
644 | avi_add( outfd, tempbuffer, filesize ); | ||
645 | delete tempbuffer; | ||
646 | framefile.close(); | ||
647 | |||
648 | } | ||
649 | |||
650 | avi_end( outfd, captureX, captureY, _framerate ); | ||
651 | ::close( outfd ); | ||
652 | ::close( infd ); | ||
653 | |||
654 | label->setText( "deleting temp files..." ); | ||
655 | qApp->processEvents(); | ||
656 | odebug << "deleting temporary capturefile " << infile << oendl; | ||
657 | QFile::remove( infile ); | ||
658 | |||
659 | fr->hide(); | ||
660 | delete fr; | ||
661 | |||
662 | updateCaption(); | ||
663 | |||
664 | } | ||
665 | |||
666 | |||
667 | void CameraMainWindow::updateCaption() | ||
668 | { | ||
669 | if ( !_capturing ) | ||
670 | setCaption( QString().sprintf( "Opie-Camera: %dx%d %s q%d z%d (%s)", captureX, captureY, (const char*) captureFormat.lower(), quality, zoom, (const char*) flip ) ); | ||
671 | else | ||
672 | setCaption( "Opie-Camera: => CAPTURING <=" ); | ||
673 | qApp->processEvents(); | ||
674 | } | ||
675 | |||
676 | |||
677 | #ifndef QT_NO_DEBUG | ||
678 | void CameraMainWindow::doSomething() | ||
679 | { | ||
680 | captureX = 240; | ||
681 | captureY = 320; | ||
682 | _videopics = 50; | ||
683 | _framerate = 5; | ||
684 | postProcessVideo( "/var/compile/opie/noncore/multimedia/camera/capture.dat", | ||
685 | "/tmp/output.avi" ); | ||
686 | } | ||
687 | #else | ||
688 | void CameraMainWindow::doSomething() | ||
689 | { | ||
690 | } | ||
691 | #endif | ||
692 | |||
diff --git a/noncore/multimedia/camera/gui/mainwindow.h b/noncore/multimedia/camera/gui/mainwindow.h new file mode 100644 index 0000000..451ad5f --- a/dev/null +++ b/noncore/multimedia/camera/gui/mainwindow.h | |||
@@ -0,0 +1,107 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2003 Michael 'Mickey' Lauer. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Opie Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | **********************************************************************/ | ||
15 | |||
16 | #ifndef MAINWINDOW_H | ||
17 | #define MAINWINDOW_H | ||
18 | |||
19 | #include <qmainwindow.h> | ||
20 | #include <qdatetime.h> | ||
21 | #include <qimage.h> | ||
22 | #include <qpixmap.h> | ||
23 | #include <qdatetime.h> | ||
24 | |||
25 | class QAction; | ||
26 | class QActionGroup; | ||
27 | class QIconSet; | ||
28 | class QTimerEvent; | ||
29 | class QToolButton; | ||
30 | class QLabel; | ||
31 | class MainWindowBase; | ||
32 | class QCopChannel; | ||
33 | class PreviewWidget; | ||
34 | |||
35 | class CameraMainWindow: public QMainWindow | ||
36 | { | ||
37 | Q_OBJECT | ||
38 | |||
39 | public: | ||
40 | CameraMainWindow( QWidget * parent = 0, const char * name = "mainwindow", WFlags f = 0 ); | ||
41 | virtual ~CameraMainWindow(); | ||
42 | |||
43 | public slots: | ||
44 | void changeZoom( int ); | ||
45 | void systemMessage( const QCString&, const QByteArray& ); | ||
46 | void showContextMenu(); | ||
47 | void resoMenuItemClicked( QAction* ); | ||
48 | void qualityMenuItemClicked( QAction* ); | ||
49 | void zoomMenuItemClicked( QAction* ); | ||
50 | void flipMenuItemClicked( QAction* ); | ||
51 | void outputToMenuItemClicked( QAction* ); | ||
52 | void outputMenuItemClicked( QAction* ); | ||
53 | void prefixItemChoosen(); | ||
54 | void appendSettingsChoosen(); | ||
55 | void shutterClicked(); | ||
56 | |||
57 | void updateCaption(); | ||
58 | |||
59 | protected: | ||
60 | void init(); | ||
61 | void startVideoCapture(); | ||
62 | void stopVideoCapture(); | ||
63 | void postProcessVideo( const QString&, const QString& ); | ||
64 | void performCapture( const QString& ); | ||
65 | |||
66 | virtual void timerEvent( QTimerEvent* ); | ||
67 | |||
68 | protected slots: | ||
69 | void doSomething(); // solely for debugging purposes | ||
70 | |||
71 | private: | ||
72 | PreviewWidget* preview; | ||
73 | int _rotation; | ||
74 | QCopChannel* _sysChannel; | ||
75 | |||
76 | QActionGroup* resog; | ||
77 | QActionGroup* qualityg; | ||
78 | QActionGroup* zoomg; | ||
79 | QActionGroup* flipg; | ||
80 | QActionGroup* outputTog; | ||
81 | QAction* custom; | ||
82 | QAction* docfolder; | ||
83 | QActionGroup* outputg; | ||
84 | |||
85 | QString flip; | ||
86 | int quality; | ||
87 | int zoom; | ||
88 | int captureX; | ||
89 | int captureY; | ||
90 | QString captureFormat; | ||
91 | |||
92 | QString outputTo; | ||
93 | QString prefix; | ||
94 | bool appendSettings; | ||
95 | |||
96 | bool _capturing; | ||
97 | int _pics; | ||
98 | int _videos; | ||
99 | |||
100 | QTime _time; | ||
101 | int _videopics; | ||
102 | int _capturefd; | ||
103 | int _framerate; | ||
104 | unsigned char* _capturebuf; | ||
105 | }; | ||
106 | |||
107 | #endif | ||
diff --git a/noncore/multimedia/camera/gui/previewwidget.cpp b/noncore/multimedia/camera/gui/previewwidget.cpp new file mode 100644 index 0000000..08330d0 --- a/dev/null +++ b/noncore/multimedia/camera/gui/previewwidget.cpp | |||
@@ -0,0 +1,88 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2002 Michael 'Mickey' Lauer. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Opie Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | **********************************************************************/ | ||
15 | |||
16 | #include "previewwidget.h" | ||
17 | #include "zcameraio.h" | ||
18 | |||
19 | #include <opie2/odebug.h> | ||
20 | |||
21 | #include <assert.h> | ||
22 | |||
23 | PreviewWidget::PreviewWidget( QWidget * parent, const char * name, WFlags f ) | ||
24 | :QLabel( parent, name, f ) | ||
25 | { | ||
26 | #ifndef QT_NO_DEBUG | ||
27 | setBackgroundColor( QColor( 255, 0, 0 ) ); | ||
28 | #else | ||
29 | setBackgroundMode( NoBackground ); | ||
30 | #endif | ||
31 | |||
32 | #ifndef QT_NO_DEBUG | ||
33 | if ( ZCameraIO::instance()->isOpen() ) startTimer( 1500 ); | ||
34 | #else | ||
35 | if ( ZCameraIO::instance()->isOpen() ) startTimer( 200 ); | ||
36 | #endif | ||
37 | }; | ||
38 | |||
39 | |||
40 | PreviewWidget::~PreviewWidget() | ||
41 | { | ||
42 | } | ||
43 | |||
44 | |||
45 | void PreviewWidget::resizeEvent( QResizeEvent* e ) | ||
46 | { | ||
47 | QLabel::resizeEvent( e ); | ||
48 | int w = e->size().width(); | ||
49 | int h = e->size().height(); | ||
50 | ZCameraIO::instance()->setCaptureFrame( e->size().width(), | ||
51 | e->size().height(), | ||
52 | 256, | ||
53 | w < h ); | ||
54 | } | ||
55 | |||
56 | |||
57 | void PreviewWidget::timerEvent( QTimerEvent* ) | ||
58 | { | ||
59 | //QDirectPainter fb( this ); | ||
60 | //ZCameraIO::instance()->snapshot( fb.frameBuffer() ); | ||
61 | |||
62 | if ( ZCameraIO::instance()->snapshot( &i ) ) | ||
63 | { | ||
64 | p.convertFromImage( i ); | ||
65 | setPixmap( p ); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | |||
70 | void PreviewWidget::mousePressEvent( QMouseEvent* ) | ||
71 | { | ||
72 | emit contextMenuRequested(); | ||
73 | } | ||
74 | |||
75 | |||
76 | void PreviewWidget::setRefreshingRate( int ms ) | ||
77 | { | ||
78 | killTimers(); | ||
79 | if ( ms ) | ||
80 | startTimer( ms ); | ||
81 | } | ||
82 | |||
83 | |||
84 | void PreviewWidget::refresh() | ||
85 | { | ||
86 | QTimerEvent t( 10 ); // event id is meaningless in this case | ||
87 | timerEvent( &t ); | ||
88 | } | ||
diff --git a/noncore/multimedia/camera/gui/previewwidget.h b/noncore/multimedia/camera/gui/previewwidget.h new file mode 100644 index 0000000..d37f80f --- a/dev/null +++ b/noncore/multimedia/camera/gui/previewwidget.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2003 Michael 'Mickey' Lauer. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Opie Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | **********************************************************************/ | ||
15 | |||
16 | #ifndef PREVIEWWIDGET_H | ||
17 | #define PREVIEWWIDGET_H | ||
18 | |||
19 | #include <qlabel.h> | ||
20 | #include <qimage.h> | ||
21 | #include <qpixmap.h> | ||
22 | |||
23 | class QTimerEvent; | ||
24 | class QResizeEvent; | ||
25 | |||
26 | class PreviewWidget: public QLabel | ||
27 | { | ||
28 | Q_OBJECT | ||
29 | |||
30 | public: | ||
31 | PreviewWidget( QWidget * parent = 0, const char * name = 0, WFlags f = 0 ); | ||
32 | virtual ~PreviewWidget(); | ||
33 | |||
34 | void setRefreshingRate( int ms ); | ||
35 | void refresh(); | ||
36 | |||
37 | protected: | ||
38 | virtual void timerEvent( QTimerEvent* ); | ||
39 | virtual void resizeEvent( QResizeEvent* ); | ||
40 | virtual void mousePressEvent( QMouseEvent* ); | ||
41 | |||
42 | signals: | ||
43 | void contextMenuRequested(); | ||
44 | |||
45 | private: | ||
46 | QPixmap p; | ||
47 | QImage i; | ||
48 | }; | ||
49 | |||
50 | #endif | ||
diff --git a/noncore/multimedia/camera/lib/.cvsignore b/noncore/multimedia/camera/lib/.cvsignore index 737c5b2..2a3a7a8 100644 --- a/noncore/multimedia/camera/lib/.cvsignore +++ b/noncore/multimedia/camera/lib/.cvsignore | |||
@@ -1 +1,2 @@ | |||
1 | *.pro | ||
1 | moc | 2 | moc |