-rw-r--r-- | noncore/multimedia/camera/imageio.cpp | 4 | ||||
-rw-r--r-- | noncore/multimedia/camera/mainwindow.cpp | 46 | ||||
-rw-r--r-- | noncore/multimedia/camera/opie-camera.control | 2 |
3 files changed, 40 insertions, 12 deletions
diff --git a/noncore/multimedia/camera/imageio.cpp b/noncore/multimedia/camera/imageio.cpp index f8f5dd0..ed0d39f 100644 --- a/noncore/multimedia/camera/imageio.cpp +++ b/noncore/multimedia/camera/imageio.cpp | |||
@@ -1,55 +1,55 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2002 Michael 'Mickey' Lauer. All rights reserved. | 2 | ** Copyright (C) 2002 Michael 'Mickey' Lauer. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Opie Environment. | 4 | ** This file is part of Opie Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 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 | 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 | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 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. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | **********************************************************************/ | 14 | **********************************************************************/ |
15 | 15 | ||
16 | #include "imageio.h" | 16 | #include "imageio.h" |
17 | 17 | ||
18 | #include <opie2/odebug.h> | 18 | #include <opie2/odebug.h> |
19 | #include <qimage.h> | 19 | #include <qimage.h> |
20 | 20 | ||
21 | 21 | ||
22 | void bufferToImage( int _width, int _height, unsigned char* bp, QImage* image ) | 22 | void bufferToImage( int _width, int _height, unsigned char* bp, QImage* image ) |
23 | { | 23 | { |
24 | unsigned char* p; | 24 | unsigned char* p; |
25 | 25 | ||
26 | image->create( _width, _height, 16 ); | 26 | image->create( _width, _height, 16 ); |
27 | for ( int i = 0; i < _height; ++i ) | 27 | for ( int i = 0; i < _height; ++i ) |
28 | { | 28 | { |
29 | p = image->scanLine( i ); | 29 | p = image->scanLine( i ); |
30 | for ( int j = 0; j < _width; j++ ) | 30 | for ( int j = 0; j < _width; j++ ) |
31 | { | 31 | { |
32 | *p = *bp; | 32 | *p = *bp; |
33 | p++; | 33 | p++; |
34 | bp++; | 34 | bp++; |
35 | *p = *bp; | 35 | *p = *bp; |
36 | p++; | 36 | p++; |
37 | bp++; | 37 | bp++; |
38 | } | 38 | } |
39 | } | 39 | } |
40 | } | 40 | } |
41 | 41 | ||
42 | 42 | ||
43 | void imageToFile( QImage* i, const QString& name, const QString& format, int quality ) | 43 | void imageToFile( QImage* i, const QString& name, const QString& format, int quality ) |
44 | { | 44 | { |
45 | QImage im = i->convertDepth( 32 ); | 45 | QImage im = i->convertDepth( 32 ); |
46 | bool result = im.save( name, format, quality ); | 46 | bool result = im.save( name, format, quality ); |
47 | if ( !result ) | 47 | if ( !result ) |
48 | { | 48 | { |
49 | oerr << "imageio-Problem while writing." << oendl; | 49 | oerr << "imageio-Problem while writing to " << name << oendl; |
50 | } | 50 | } |
51 | else | 51 | else |
52 | { | 52 | { |
53 | odebug << format << "-image has been successfully captured" << oendl; | 53 | odebug << format << "-image has been successfully captured" << oendl; |
54 | } | 54 | } |
55 | } \ No newline at end of file | 55 | } |
diff --git a/noncore/multimedia/camera/mainwindow.cpp b/noncore/multimedia/camera/mainwindow.cpp index 16ee8bc..49c7cbf 100644 --- a/noncore/multimedia/camera/mainwindow.cpp +++ b/noncore/multimedia/camera/mainwindow.cpp | |||
@@ -97,131 +97,131 @@ CameraMainWindow::CameraMainWindow( QWidget * parent, const char * name, WFlags | |||
97 | 97 | ||
98 | connect( preview, SIGNAL( contextMenuRequested() ), this, SLOT( showContextMenu() ) ); | 98 | connect( preview, SIGNAL( contextMenuRequested() ), this, SLOT( showContextMenu() ) ); |
99 | 99 | ||
100 | connect( ZCameraIO::instance(), SIGNAL( shutterClicked() ), this, SLOT( shutterClicked() ) ); | 100 | connect( ZCameraIO::instance(), SIGNAL( shutterClicked() ), this, SLOT( shutterClicked() ) ); |
101 | 101 | ||
102 | updateCaption(); | 102 | updateCaption(); |
103 | 103 | ||
104 | }; | 104 | }; |
105 | 105 | ||
106 | 106 | ||
107 | CameraMainWindow::~CameraMainWindow() | 107 | CameraMainWindow::~CameraMainWindow() |
108 | { | 108 | { |
109 | } | 109 | } |
110 | 110 | ||
111 | 111 | ||
112 | void CameraMainWindow::init() | 112 | void CameraMainWindow::init() |
113 | { | 113 | { |
114 | // TODO: Save this stuff in config | 114 | // TODO: Save this stuff in config |
115 | flip = 'A'; // auto | 115 | flip = 'A'; // auto |
116 | quality = 50; | 116 | quality = 50; |
117 | zoom = 1; | 117 | zoom = 1; |
118 | captureX = 480; | 118 | captureX = 480; |
119 | captureY = 640; | 119 | captureY = 640; |
120 | captureFormat = "JPEG"; | 120 | captureFormat = "JPEG"; |
121 | outputTo = "Documents Folder"; | 121 | outputTo = "Documents Folder"; |
122 | prefix = "Untitled"; | 122 | prefix = "Untitled"; |
123 | appendSettings = true; | 123 | appendSettings = true; |
124 | 124 | ||
125 | resog = new QActionGroup( 0, "reso", true ); | 125 | resog = new QActionGroup( 0, "reso", true ); |
126 | resog->setToggleAction( true ); | 126 | resog->setToggleAction( true ); |
127 | new QAction( " 64 x 48", 0, 0, resog, 0, true ); | 127 | new QAction( " 64 x 48", 0, 0, resog, 0, true ); |
128 | new QAction( "128 x 96", 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 ); | 129 | new QAction( "192 x 144", 0, 0, resog, 0, true ); |
130 | new QAction( "256 x 192", 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 ); | 131 | new QAction( "320 x 240", 0, 0, resog, 0, true ); |
132 | new QAction( "384 x 288", 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 ); | 133 | new QAction( "448 x 336", 0, 0, resog, 0, true ); |
134 | new QAction( "512 x 384", 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 ); | 135 | new QAction( "576 x 432", 0, 0, resog, 0, true ); |
136 | ( new QAction( "640 x 480", 0, 0, resog, 0, true ) )->setOn( true ); | 136 | ( new QAction( "640 x 480", 0, 0, resog, 0, true ) )->setOn( true ); |
137 | 137 | ||
138 | qualityg = new QActionGroup( 0, "quality", true ); | 138 | qualityg = new QActionGroup( 0, "quality", true ); |
139 | qualityg->setToggleAction( true ); | 139 | qualityg->setToggleAction( true ); |
140 | new QAction( " 0 (&minimal)", 0, 0, qualityg, 0, true ); | 140 | new QAction( " 0 (&minimal)", 0, 0, qualityg, 0, true ); |
141 | new QAction( " 25 (&low)", 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 ); | 142 | ( new QAction( " 50 (&good)", 0, 0, qualityg, 0, true ) )->setOn( true ); |
143 | new QAction( " 75 (&better)", 0, 0, qualityg, 0, true ); | 143 | new QAction( " 75 (&better)", 0, 0, qualityg, 0, true ); |
144 | new QAction( "100 (bes&t)", 0, 0, qualityg, 0, true ); | 144 | new QAction( "100 (bes&t)", 0, 0, qualityg, 0, true ); |
145 | 145 | ||
146 | zoomg = new QActionGroup( 0, "zoom", true ); | 146 | zoomg = new QActionGroup( 0, "zoom", true ); |
147 | zoomg->setToggleAction( true ); | 147 | zoomg->setToggleAction( true ); |
148 | ( new QAction( "x 1", 0, 0, zoomg, 0, true ) )->setOn( true ); | 148 | ( new QAction( "x 1", 0, 0, zoomg, 0, true ) )->setOn( true ); |
149 | new QAction( "x 2", 0, 0, zoomg, 0, true ); | 149 | new QAction( "x 2", 0, 0, zoomg, 0, true ); |
150 | 150 | ||
151 | flipg = new QActionGroup( 0, "flip", true ); | 151 | flipg = new QActionGroup( 0, "flip", true ); |
152 | flipg->setToggleAction( true ); | 152 | flipg->setToggleAction( true ); |
153 | ( new QAction( "Auto (recommended)", 0, 0, flipg, 0, true ) )->setOn( true ); | 153 | ( new QAction( "Auto (recommended)", 0, 0, flipg, 0, true ) )->setOn( true ); |
154 | new QAction( "0 (always off)", 0, 0, flipg, 0, true ); | 154 | new QAction( "0 (always off)", 0, 0, flipg, 0, true ); |
155 | new QAction( "X (always horizontal)", 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 ); | 156 | new QAction( "Y (always vertical)", 0, 0, flipg, 0, true ); |
157 | new QAction( "* (always both)", 0, 0, flipg, 0, true ); | 157 | new QAction( "* (always both)", 0, 0, flipg, 0, true ); |
158 | 158 | ||
159 | outputTog = new QActionGroup( 0, "output", true ); | 159 | outputTog = new QActionGroup( 0, "output", true ); |
160 | outputTog->setToggleAction( true ); | 160 | outputTog->setToggleAction( true ); |
161 | new QAction( "/tmp", 0, 0, outputTog, 0, true ); | 161 | new QAction( "/tmp/", 0, 0, outputTog, 0, true ); |
162 | new QAction( "/mnt/card/", 0, 0, outputTog, 0, true ); | 162 | new QAction( "/mnt/card/", 0, 0, outputTog, 0, true ); |
163 | new QAction( "/mnt/sd/", 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 ); | 164 | docfolder = new QAction( "Documents Folder", 0, 0, outputTog, 0, true ); |
165 | docfolder->setOn( true ); | 165 | docfolder->setOn( true ); |
166 | custom = new QAction( "&Custom...", 0, 0, outputTog, 0, true ); | 166 | custom = new QAction( "&Custom...", 0, 0, outputTog, 0, true ); |
167 | 167 | ||
168 | outputg = new QActionGroup( 0, "output", true ); | 168 | outputg = new QActionGroup( 0, "output", true ); |
169 | outputg->setToggleAction( true ); | 169 | outputg->setToggleAction( true ); |
170 | ( new QAction( "JPEG", 0, 0, outputg, 0, true ) )->setOn( true ); | 170 | ( new QAction( "JPEG", 0, 0, outputg, 0, true ) )->setOn( true ); |
171 | new QAction( "PNG", 0, 0, outputg, 0, true ); | 171 | new QAction( "PNG", 0, 0, outputg, 0, true ); |
172 | new QAction( "BMP", 0, 0, outputg, 0, true ); | 172 | new QAction( "BMP", 0, 0, outputg, 0, true ); |
173 | new QAction( "AVI", 0, 0, outputg, 0, true ); | 173 | new QAction( "AVI", 0, 0, outputg, 0, true ); |
174 | 174 | ||
175 | connect( resog, SIGNAL( selected(QAction*) ), this, SLOT( resoMenuItemClicked(QAction*) ) ); | 175 | connect( resog, SIGNAL( selected(QAction*) ), this, SLOT( resoMenuItemClicked(QAction*) ) ); |
176 | connect( qualityg, SIGNAL( selected(QAction*) ), this, SLOT( qualityMenuItemClicked(QAction*) ) ); | 176 | connect( qualityg, SIGNAL( selected(QAction*) ), this, SLOT( qualityMenuItemClicked(QAction*) ) ); |
177 | connect( zoomg, SIGNAL( selected(QAction*) ), this, SLOT( zoomMenuItemClicked(QAction*) ) ); | 177 | connect( zoomg, SIGNAL( selected(QAction*) ), this, SLOT( zoomMenuItemClicked(QAction*) ) ); |
178 | connect( flipg, SIGNAL( selected(QAction*) ), this, SLOT( flipMenuItemClicked(QAction*) ) ); | 178 | connect( flipg, SIGNAL( selected(QAction*) ), this, SLOT( flipMenuItemClicked(QAction*) ) ); |
179 | connect( outputTog, SIGNAL( selected(QAction*) ), this, SLOT( outputToMenuItemClicked(QAction*) ) ); | 179 | connect( outputTog, SIGNAL( selected(QAction*) ), this, SLOT( outputToMenuItemClicked(QAction*) ) ); |
180 | connect( outputg, SIGNAL( selected(QAction*) ), this, SLOT( outputMenuItemClicked(QAction*) ) ); | 180 | connect( outputg, SIGNAL( selected(QAction*) ), this, SLOT( outputMenuItemClicked(QAction*) ) ); |
181 | 181 | ||
182 | } | 182 | } |
183 | 183 | ||
184 | 184 | ||
185 | void CameraMainWindow::systemMessage( const QCString& msg, const QByteArray& data ) | 185 | void CameraMainWindow::systemMessage( const QCString& msg, const QByteArray& data ) |
186 | { | 186 | { |
187 | int _newrotation; | 187 | int _newrotation; |
188 | 188 | ||
189 | QDataStream stream( data, IO_ReadOnly ); | 189 | QDataStream stream( data, IO_ReadOnly ); |
190 | odebug << "received system message: " << msg << oendl; | 190 | odebug << "received system message: " << msg << oendl; |
191 | if ( msg == "setCurrentRotation(int)" ) | 191 | if ( msg == "setCurrentRotation(int)" ) |
192 | { | 192 | { |
193 | stream >> _newrotation; | 193 | stream >> _newrotation; |
194 | odebug << "received setCurrentRotation(" << _newrotation << ")" << oendl; | 194 | odebug << "received setCurrentRotation(" << _newrotation << ")" << oendl; |
195 | 195 | ||
196 | switch ( _newrotation ) | 196 | switch ( _newrotation ) |
197 | { | 197 | { |
198 | case 270: preview->resize( QSize( 240, 288 ) ); break; | 198 | case 270: preview->resize( QSize( 240, 288 ) ); break; |
199 | case 180: preview->resize( QSize( 320, 208 ) ); break; | 199 | case 180: preview->resize( QSize( 320, 208 ) ); break; |
200 | default: QMessageBox::warning( this, "opie-camera", | 200 | default: QMessageBox::warning( this, "opie-camera", |
201 | "This rotation is not supported.\n" | 201 | "This rotation is not supported.\n" |
202 | "Supported are 180° and 270°" ); | 202 | "Supported are 180° and 270°" ); |
203 | } | 203 | } |
204 | 204 | ||
205 | if ( _newrotation != _rotation ) | 205 | if ( _newrotation != _rotation ) |
206 | { | 206 | { |
207 | int tmp = captureX; | 207 | int tmp = captureX; |
208 | captureX = captureY; | 208 | captureX = captureY; |
209 | captureY = tmp; | 209 | captureY = tmp; |
210 | _rotation = _newrotation; | 210 | _rotation = _newrotation; |
211 | } | 211 | } |
212 | 212 | ||
213 | updateCaption(); | 213 | updateCaption(); |
214 | 214 | ||
215 | } | 215 | } |
216 | } | 216 | } |
217 | 217 | ||
218 | 218 | ||
219 | void CameraMainWindow::changeZoom( int zoom ) | 219 | void CameraMainWindow::changeZoom( int zoom ) |
220 | { | 220 | { |
221 | int z; | 221 | int z; |
222 | switch ( zoom ) | 222 | switch ( zoom ) |
223 | { | 223 | { |
224 | case 0: z = 128; break; | 224 | case 0: z = 128; break; |
225 | case 1: z = 256; break; | 225 | case 1: z = 256; break; |
226 | case 2: z = 512; break; | 226 | case 2: z = 512; break; |
227 | default: assert( 0 ); break; | 227 | default: assert( 0 ); break; |
@@ -361,304 +361,332 @@ void CameraMainWindow::outputToMenuItemClicked( QAction* a ) | |||
361 | outputTo = str; | 361 | outputTo = str; |
362 | } | 362 | } |
363 | } | 363 | } |
364 | else | 364 | else |
365 | { | 365 | { |
366 | outputTo = a->text(); | 366 | outputTo = a->text(); |
367 | } | 367 | } |
368 | odebug << "Output to now: " << outputTo << oendl; | 368 | odebug << "Output to now: " << outputTo << oendl; |
369 | } | 369 | } |
370 | 370 | ||
371 | 371 | ||
372 | void CameraMainWindow::outputMenuItemClicked( QAction* a ) | 372 | void CameraMainWindow::outputMenuItemClicked( QAction* a ) |
373 | { | 373 | { |
374 | captureFormat = a->text(); | 374 | captureFormat = a->text(); |
375 | odebug << "Output format now: " << captureFormat << oendl; | 375 | odebug << "Output format now: " << captureFormat << oendl; |
376 | updateCaption(); | 376 | updateCaption(); |
377 | } | 377 | } |
378 | 378 | ||
379 | 379 | ||
380 | void CameraMainWindow::prefixItemChoosen() | 380 | void CameraMainWindow::prefixItemChoosen() |
381 | { | 381 | { |
382 | QDialog* d = new QDialog( this, "dialog", true ); | 382 | QDialog* d = new QDialog( this, "dialog", true ); |
383 | d->setCaption( "Enter Prefix..." ); | 383 | d->setCaption( "Enter Prefix..." ); |
384 | QVBoxLayout* v = new QVBoxLayout( d ); | 384 | QVBoxLayout* v = new QVBoxLayout( d ); |
385 | QLineEdit* le = new QLineEdit( prefix, d ); | 385 | QLineEdit* le = new QLineEdit( prefix, d ); |
386 | v->addWidget( le ); | 386 | v->addWidget( le ); |
387 | le->setFixedWidth( 150 ); //FIXME: 'tis a bit dirty | 387 | le->setFixedWidth( 150 ); //FIXME: 'tis a bit dirty |
388 | if ( d->exec() == QDialog::Accepted ) | 388 | if ( d->exec() == QDialog::Accepted ) |
389 | prefix = le->text(); | 389 | prefix = le->text(); |
390 | odebug << "Prefix now: " << prefix << oendl; | 390 | odebug << "Prefix now: " << prefix << oendl; |
391 | } | 391 | } |
392 | 392 | ||
393 | 393 | ||
394 | void CameraMainWindow::appendSettingsChoosen() | 394 | void CameraMainWindow::appendSettingsChoosen() |
395 | { | 395 | { |
396 | appendSettings = !appendSettings; | 396 | appendSettings = !appendSettings; |
397 | odebug << "appendSettings now: " << appendSettings << oendl; | 397 | odebug << "appendSettings now: " << appendSettings << oendl; |
398 | } | 398 | } |
399 | 399 | ||
400 | 400 | ||
401 | void CameraMainWindow::shutterClicked() | 401 | void CameraMainWindow::shutterClicked() |
402 | { | 402 | { |
403 | if ( captureFormat != "AVI" ) // capture one photo per shutterClick | 403 | if ( captureFormat != "AVI" ) // capture one photo per shutterClick |
404 | { | 404 | { |
405 | Global::statusMessage( "CAPTURING..." ); | 405 | Global::statusMessage( "CAPTURING..." ); |
406 | qApp->processEvents(); | 406 | qApp->processEvents(); |
407 | 407 | ||
408 | odebug << "Shutter has been pressed" << oendl; | 408 | odebug << "Shutter has been pressed" << oendl; |
409 | ODevice::inst()->touchSound(); | 409 | ODevice::inst()->touchSound(); |
410 | 410 | ||
411 | performCapture( captureFormat ); | 411 | performCapture( captureFormat ); |
412 | } | 412 | } |
413 | else // capture video! start with one shutter click and stop with the next | 413 | else // capture video! start with one shutter click and stop with the next |
414 | { | 414 | { |
415 | !_capturing ? startVideoCapture() : stopVideoCapture(); | 415 | !_capturing ? startVideoCapture() : stopVideoCapture(); |
416 | } | 416 | } |
417 | } | 417 | } |
418 | 418 | ||
419 | 419 | ||
420 | void CameraMainWindow::performCapture( const QString& format ) | 420 | void CameraMainWindow::performCapture( const QString& format ) |
421 | { | 421 | { |
422 | QString name; | 422 | QString name; |
423 | 423 | ||
424 | if ( outputTo == "Documents Folder" ) | 424 | if ( outputTo == "Documents Folder" ) |
425 | name.sprintf( "%s/Documents/image/%s/", (const char*) QDir::homeDirPath(), (const char*) captureFormat.lower() ); | 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 | } | ||
426 | else | 434 | else |
427 | name = outputTo; | 435 | name = outputTo; |
428 | 436 | ||
429 | name.append( prefix ); | 437 | name.append( prefix ); |
430 | if ( appendSettings ) | 438 | if ( appendSettings ) |
431 | { | 439 | { |
432 | name.append( QString().sprintf( "_%d_%d_q%d", captureX, captureY, quality ) ); | 440 | name.append( QString().sprintf( "_%d_%d_q%d", captureX, captureY, quality ) ); |
433 | } | 441 | } |
434 | name.append( QString().sprintf( "-%d.%s", _pics++, (const char*) captureFormat.lower() ) ); | 442 | name.append( QString().sprintf( "-%d.%s", _pics++, (const char*) captureFormat.lower() ) ); |
435 | 443 | ||
436 | QImage i; | 444 | QImage i; |
437 | ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, &i ); | 445 | ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, &i ); |
438 | QImage im = i.convertDepth( 32 ); | 446 | QImage im = i.convertDepth( 32 ); |
439 | bool result = im.save( name, format, quality ); | 447 | bool result = im.save( name, format, quality ); |
440 | if ( !result ) | 448 | if ( !result ) |
441 | { | 449 | { |
442 | oerr << "imageio-Problem while writing." << oendl; | 450 | oerr << "imageio-Problem while writing." << oendl; |
443 | Global::statusMessage( "Error!" ); | 451 | Global::statusMessage( "Error!" ); |
444 | } | 452 | } |
445 | else | 453 | else |
446 | { | 454 | { |
447 | odebug << captureFormat << "-image has been successfully captured" << oendl; | 455 | odebug << captureFormat << "-image has been successfully captured" << oendl; |
448 | Global::statusMessage( "Ok." ); | 456 | Global::statusMessage( "Ok." ); |
449 | } | 457 | } |
450 | } | 458 | } |
451 | 459 | ||
452 | 460 | ||
453 | void CameraMainWindow::startVideoCapture() | 461 | void CameraMainWindow::startVideoCapture() |
454 | { | 462 | { |
455 | //ODevice::inst()->touchSound(); | 463 | //ODevice::inst()->touchSound(); |
456 | ODevice::inst()->setLedState( Led_Mail, Led_BlinkSlow ); | 464 | ODevice::inst()->setLedState( Led_Mail, Led_BlinkSlow ); |
457 | 465 | ||
458 | _capturefd = ::open( CAPTUREFILE, O_WRONLY | O_CREAT | O_TRUNC ); | 466 | _capturefd = ::open( CAPTUREFILE, O_WRONLY | O_CREAT | O_TRUNC ); |
459 | if ( _capturefd == -1 ) | 467 | if ( _capturefd == -1 ) |
460 | { | 468 | { |
461 | owarn << "can't open capture file: " << strerror(errno) << oendl; | 469 | owarn << "can't open capture file: " << strerror(errno) << oendl; |
462 | return; | 470 | return; |
463 | } | 471 | } |
464 | 472 | ||
465 | _capturebuf = new unsigned char[captureX*captureY*2]; | 473 | _capturebuf = new unsigned char[captureX*captureY*2]; |
466 | _capturing = true; | 474 | _capturing = true; |
467 | _videopics = 0; | 475 | _videopics = 0; |
468 | _framerate = 0; | 476 | _framerate = 0; |
469 | updateCaption(); | 477 | updateCaption(); |
470 | _time.start(); | 478 | _time.start(); |
471 | preview->setRefreshingRate( 1000 ); | 479 | preview->setRefreshingRate( 1000 ); |
472 | startTimer( 100 ); // too fast but that is ok | 480 | startTimer( 100 ); // too fast but that is ok |
473 | } | 481 | } |
474 | 482 | ||
475 | 483 | ||
476 | void CameraMainWindow::timerEvent( QTimerEvent* ) | 484 | void CameraMainWindow::timerEvent( QTimerEvent* ) |
477 | { | 485 | { |
478 | if ( !_capturing ) | 486 | if ( !_capturing ) |
479 | { | 487 | { |
480 | odebug << "timer event in CameraMainWindow without capturing video ?" << oendl; | 488 | odebug << "timer event in CameraMainWindow without capturing video ?" << oendl; |
481 | return; | 489 | return; |
482 | } | 490 | } |
483 | 491 | ||
484 | odebug << "timer event during video - now capturing frame #" << _videopics+1 << oendl; | 492 | odebug << "timer event during video - now capturing frame #" << _videopics+1 << oendl; |
485 | 493 | ||
486 | ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, _capturebuf ); | 494 | ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, _capturebuf ); |
487 | _videopics++; | 495 | _videopics++; |
488 | ::write( _capturefd, _capturebuf, captureX*captureY*2 ); | 496 | ::write( _capturefd, _capturebuf, captureX*captureY*2 ); |
489 | setCaption( QString().sprintf( "Capturing %dx%d @ %.2f fps %d", | 497 | setCaption( QString().sprintf( "Capturing %dx%d @ %.2f fps %d", |
490 | captureX, captureY, 1000.0 / (_time.elapsed()/_videopics), _videopics ) ); | 498 | captureX, captureY, 1000.0 / (_time.elapsed()/_videopics), _videopics ) ); |
491 | } | 499 | } |
492 | 500 | ||
493 | 501 | ||
494 | void CameraMainWindow::stopVideoCapture() | 502 | void CameraMainWindow::stopVideoCapture() |
495 | { | 503 | { |
496 | killTimers(); | 504 | killTimers(); |
497 | //ODevice::inst()->touchSound(); | 505 | //ODevice::inst()->touchSound(); |
498 | ODevice::inst()->setLedState( Led_Mail, Led_Off ); | 506 | ODevice::inst()->setLedState( Led_Mail, Led_Off ); |
499 | _capturing = false; | 507 | _capturing = false; |
500 | updateCaption(); | 508 | updateCaption(); |
501 | ::close( _capturefd ); | 509 | ::close( _capturefd ); |
502 | _framerate = 1000.0 / (_time.elapsed()/_videopics); | 510 | _framerate = 1000.0 / (_time.elapsed()/_videopics); |
503 | 511 | ||
504 | QString name( outputTo ); | 512 | QString name; |
505 | name.append( "/prefix" ); | 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 ); | ||
506 | if ( appendSettings ) | 528 | if ( appendSettings ) |
507 | name.append( QString().sprintf( "_%d_%d_q%d_%dfps", captureX, captureY, quality, _framerate ) ); | 529 | name.append( QString().sprintf( "_%d_%d_q%d_%dfps", captureX, captureY, quality, _framerate ) ); |
508 | name.append( QString().sprintf( "-%d.%s", _videos++, (const char*) captureFormat.lower() ) ); | 530 | name.append( QString().sprintf( "-%d.%s", _videos++, (const char*) captureFormat.lower() ) ); |
509 | postProcessVideo( CAPTUREFILE, name ); | 531 | postProcessVideo( CAPTUREFILE, name ); |
510 | 532 | ||
511 | #ifndef QT_NO_DEBUG | 533 | #ifndef QT_NO_DEBUG |
512 | preview->setRefreshingRate( 1500 ); | 534 | preview->setRefreshingRate( 1500 ); |
513 | #else | 535 | #else |
514 | preview->setRefreshingRate( 200 ); | 536 | preview->setRefreshingRate( 200 ); |
515 | #endif | 537 | #endif |
516 | 538 | ||
517 | //delete[] _capturebuf; //FIXME: close memory leak | 539 | //delete[] _capturebuf; //FIXME: close memory leak |
518 | } | 540 | } |
519 | 541 | ||
520 | void CameraMainWindow::postProcessVideo( const QString& infile, const QString& outfile ) | 542 | void CameraMainWindow::postProcessVideo( const QString& infile, const QString& outfile ) |
521 | { | 543 | { |
544 | odebug << "post processing " << infile << " --> " << outfile << oendl; | ||
545 | |||
522 | preview->setRefreshingRate( 0 ); | 546 | preview->setRefreshingRate( 0 ); |
523 | 547 | ||
524 | /* | 548 | /* |
525 | unsigned char buf[153600]; | 549 | unsigned char buf[153600]; |
526 | 550 | ||
527 | int fd = ::open( "/var/compile/opie/noncore/multimedia/camera/capture-320x240.dat", O_RDONLY ); | 551 | int fd = ::open( "/var/compile/opie/noncore/multimedia/camera/capture-320x240.dat", O_RDONLY ); |
528 | ::read( fd, &buf, 153600 ); | 552 | ::read( fd, &buf, 153600 ); |
529 | QImage i; | 553 | QImage i; |
530 | bufferToImage( 240, 320, (unsigned char*) &buf, &i ); | 554 | bufferToImage( 240, 320, (unsigned char*) &buf, &i ); |
531 | QPixmap p; | 555 | QPixmap p; |
532 | p.convertFromImage( i ); | 556 | p.convertFromImage( i ); |
533 | preview->setPixmap( p ); | 557 | preview->setPixmap( p ); |
534 | imageToFile( &i, "/tmp/tmpfile", "JPEG", 100 ); | 558 | imageToFile( &i, "/tmp/tmpfile", "JPEG", 100 ); |
535 | return; | 559 | return; |
536 | */ | 560 | */ |
537 | 561 | ||
538 | QDialog* fr = new QDialog( this, "splash", false, QWidget::WStyle_StaysOnTop ); //, false, QWidget::WStyle_NoBorder | QWidget::WStyle_Customize ); | 562 | QDialog* fr = new QDialog( this, "splash", false, QWidget::WStyle_StaysOnTop ); //, false, QWidget::WStyle_NoBorder | QWidget::WStyle_Customize ); |
539 | fr->setCaption( "Please wait..." ); | 563 | fr->setCaption( "Please wait..." ); |
540 | QVBoxLayout* box = new QVBoxLayout( fr, 2, 2 ); | 564 | QVBoxLayout* box = new QVBoxLayout( fr, 2, 2 ); |
541 | QProgressBar* bar = new QProgressBar( fr ); | 565 | QProgressBar* bar = new QProgressBar( fr ); |
542 | bar->setCenterIndicator( true ); | 566 | bar->setCenterIndicator( true ); |
543 | bar->setTotalSteps( _videopics-1 ); | 567 | bar->setTotalSteps( _videopics-1 ); |
544 | QLabel* label = new QLabel( "Post processing frame bla/bla", fr ); | 568 | QLabel* label = new QLabel( "Post processing frame bla/bla", fr ); |
545 | box->addWidget( bar ); | 569 | box->addWidget( bar ); |
546 | box->addWidget( label ); | 570 | box->addWidget( label ); |
547 | fr->show(); | 571 | fr->show(); |
548 | label->show(); | 572 | label->show(); |
549 | bar->show(); | 573 | bar->show(); |
550 | fr->repaint(); | 574 | fr->repaint(); |
551 | qApp->processEvents(); | 575 | qApp->processEvents(); |
552 | 576 | ||
553 | // open files | 577 | // open files |
554 | 578 | ||
555 | int infd = ::open( (const char*) infile, O_RDONLY ); | 579 | int infd = ::open( (const char*) infile, O_RDONLY ); |
556 | if ( infd == -1 ) | 580 | if ( infd == -1 ) |
557 | { | 581 | { |
558 | owarn << "couldn't open capture file: " << strerror(errno) << oendl; | 582 | owarn << "couldn't open capture file: " << strerror(errno) << oendl; |
559 | return; | 583 | return; |
560 | } | 584 | } |
561 | 585 | ||
562 | int outfd = ::open( (const char*) outfile, O_CREAT | O_WRONLY | O_TRUNC, 0644 ); | 586 | int outfd = ::open( (const char*) outfile, O_CREAT | O_WRONLY | O_TRUNC, 0644 ); |
563 | if ( outfd == -1 ) | 587 | if ( outfd == -1 ) |
564 | { | 588 | { |
565 | owarn << "couldn't open output file: " << strerror(errno) << oendl; | 589 | owarn << "couldn't open output file: " << strerror(errno) << oendl; |
566 | return; | 590 | return; |
567 | } | 591 | } |
568 | 592 | ||
569 | int framesize = captureX*captureY*2; | 593 | int framesize = captureX*captureY*2; |
570 | 594 | ||
571 | unsigned char* inbuffer = new unsigned char[ framesize ]; | 595 | unsigned char* inbuffer = new unsigned char[ framesize ]; |
572 | QImage image; | 596 | QImage image; |
573 | 597 | ||
574 | avi_start( outfd, _videopics ); // write preambel | 598 | avi_start( outfd, _videopics ); // write preambel |
575 | 599 | ||
576 | // post process | 600 | // post process |
577 | 601 | ||
578 | for ( int i = 0; i < _videopics; ++i ) | 602 | for ( int i = 0; i < _videopics; ++i ) |
579 | { | 603 | { |
580 | odebug << "processing frame " << i << oendl; | 604 | odebug << "processing frame " << i << oendl; |
581 | 605 | ||
582 | // <gui> | 606 | // <gui> |
583 | label->setText( QString().sprintf( "Post processing frame %d / %d", i+1, _videopics ) ); | 607 | label->setText( QString().sprintf( "Post processing frame %d / %d", i+1, _videopics ) ); |
584 | bar->setProgress( i ); | 608 | bar->setProgress( i ); |
585 | bar->repaint(); | 609 | bar->repaint(); |
586 | qApp->processEvents(); | 610 | qApp->processEvents(); |
587 | // </gui> | 611 | // </gui> |
588 | 612 | ||
589 | int read = ::read( infd, inbuffer, framesize ); | 613 | int read = ::read( infd, inbuffer, framesize ); |
590 | odebug << "read " << read << " bytes" << oendl; | 614 | odebug << "read " << read << " bytes" << oendl; |
591 | bufferToImage( captureX, captureY, inbuffer, &image ); | 615 | bufferToImage( captureX, captureY, inbuffer, &image ); |
592 | 616 | ||
593 | QPixmap p; | 617 | QPixmap p; |
594 | p.convertFromImage( image ); | 618 | p.convertFromImage( image ); |
595 | preview->setPixmap( p ); | 619 | preview->setPixmap( p ); |
596 | preview->repaint(); | 620 | preview->repaint(); |
597 | qApp->processEvents(); | 621 | qApp->processEvents(); |
598 | 622 | ||
599 | #ifndef QT_NO_DEBUG | 623 | #ifdef CAMERA_EXTRA_DEBUG |
600 | QString tmpfilename; | 624 | QString tmpfilename; |
601 | tmpfilename.sprintf( "/tmp/test/%04d.jpg", i ); | 625 | tmpfilename.sprintf( "/tmp/test/%04d.jpg", i ); |
602 | #else | 626 | #else |
603 | QString tmpfilename( "/tmp/tempfile" ); | 627 | QString tmpfilename( "/tmp/tempfile" ); |
604 | #endif | 628 | #endif |
605 | 629 | ||
606 | imageToFile( &image, tmpfilename, "JPEG", quality ); | 630 | imageToFile( &image, tmpfilename, "JPEG", quality ); |
607 | 631 | ||
608 | QFile framefile( tmpfilename ); | 632 | QFile framefile( tmpfilename ); |
609 | if ( !framefile.open( IO_ReadOnly ) ) | 633 | if ( !framefile.open( IO_ReadOnly ) ) |
610 | { | 634 | { |
611 | oerr << "can't process file: %s" << strerror(errno) << oendl; | 635 | oerr << "can't process file: %s" << strerror(errno) << oendl; |
612 | return; // TODO: clean up temp ressources | 636 | return; // TODO: clean up temp ressources |
613 | } | 637 | } |
614 | 638 | ||
615 | int filesize = framefile.size(); | 639 | int filesize = framefile.size(); |
616 | odebug << "filesize for frame " << i << " = " << filesize << oendl; | 640 | odebug << "filesize for frame " << i << " = " << filesize << oendl; |
617 | 641 | ||
618 | unsigned char* tempbuffer = new unsigned char[ filesize ]; | 642 | unsigned char* tempbuffer = new unsigned char[ filesize ]; |
619 | framefile.readBlock( (char*) tempbuffer, filesize ); | 643 | framefile.readBlock( (char*) tempbuffer, filesize ); |
620 | avi_add( outfd, tempbuffer, filesize ); | 644 | avi_add( outfd, tempbuffer, filesize ); |
621 | delete tempbuffer; | 645 | delete tempbuffer; |
622 | framefile.close(); | 646 | framefile.close(); |
623 | 647 | ||
624 | odebug << "deleting temporary capturefile " << infile << oendl; | ||
625 | ::close( infd ); | ||
626 | QFile::remove( infile ); | ||
627 | } | 648 | } |
628 | 649 | ||
629 | avi_end( outfd, captureX, captureY, _framerate ); | 650 | avi_end( outfd, captureX, captureY, _framerate ); |
630 | ::close( outfd ); | 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 ); | ||
631 | 658 | ||
632 | fr->hide(); | 659 | fr->hide(); |
633 | delete fr; | 660 | delete fr; |
634 | 661 | ||
635 | updateCaption(); | 662 | updateCaption(); |
636 | 663 | ||
637 | } | 664 | } |
638 | 665 | ||
639 | 666 | ||
640 | void CameraMainWindow::updateCaption() | 667 | void CameraMainWindow::updateCaption() |
641 | { | 668 | { |
642 | if ( !_capturing ) | 669 | if ( !_capturing ) |
643 | setCaption( QString().sprintf( "Opie-Camera: %dx%d %s q%d z%d (%s)", captureX, captureY, (const char*) captureFormat.lower(), quality, zoom, (const char*) flip ) ); | 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 ) ); |
644 | else | 671 | else |
645 | setCaption( "Opie-Camera: => CAPTURING <=" ); | 672 | setCaption( "Opie-Camera: => CAPTURING <=" ); |
673 | qApp->processEvents(); | ||
646 | } | 674 | } |
647 | 675 | ||
648 | 676 | ||
649 | #ifndef QT_NO_DEBUG | 677 | #ifndef QT_NO_DEBUG |
650 | void CameraMainWindow::doSomething() | 678 | void CameraMainWindow::doSomething() |
651 | { | 679 | { |
652 | captureX = 240; | 680 | captureX = 240; |
653 | captureY = 320; | 681 | captureY = 320; |
654 | _videopics = 50; | 682 | _videopics = 50; |
655 | _framerate = 5; | 683 | _framerate = 5; |
656 | postProcessVideo( "/var/compile/opie/noncore/multimedia/camera/capture.dat", | 684 | postProcessVideo( "/var/compile/opie/noncore/multimedia/camera/capture.dat", |
657 | "/tmp/output.avi" ); | 685 | "/tmp/output.avi" ); |
658 | } | 686 | } |
659 | #else | 687 | #else |
660 | void CameraMainWindow::doSomething() | 688 | void CameraMainWindow::doSomething() |
661 | { | 689 | { |
662 | } | 690 | } |
663 | #endif | 691 | #endif |
664 | 692 | ||
diff --git a/noncore/multimedia/camera/opie-camera.control b/noncore/multimedia/camera/opie-camera.control index a33de38..1731ad2 100644 --- a/noncore/multimedia/camera/opie-camera.control +++ b/noncore/multimedia/camera/opie-camera.control | |||
@@ -1,10 +1,10 @@ | |||
1 | Package: opie-camera | 1 | Package: opie-camera |
2 | Files: bin/opiecam pics/camera apps/Applications/camera.desktop | 2 | Files: bin/opiecam pics/camera apps/Applications/camera.desktop |
3 | Priority: optional | 3 | Priority: optional |
4 | Section: opie/applications | 4 | Section: opie/applications |
5 | Maintainer: Michael 'Mickey' Lauer <mickeyl@handhelds.org> | 5 | Maintainer: Michael 'Mickey' Lauer <mickeyl@handhelds.org> |
6 | Architecture: arm | 6 | Architecture: arm |
7 | Version: $QPE_VERSION-$SUB_VERSION | 7 | Version: 1.0 |
8 | Depends: task-opie-minimal, libopie2 (1.8.1) | 8 | Depends: task-opie-minimal, libopie2 (1.8.1) |
9 | Description: A Camera Application | 9 | Description: A Camera Application |
10 | A Camera Application to use with the Sharp CE-AG06. | 10 | A Camera Application to use with the Sharp CE-AG06. |