129 } |
133 } |
130 |
134 |
131 /*! |
135 /*! |
132 * Calculate snapshot size based on diplay size and image / video output resolution. |
136 * Calculate snapshot size based on diplay size and image / video output resolution. |
133 * @param displaySize Display size in pixels. |
137 * @param displaySize Display size in pixels. |
134 * @param outputResolution Resolution of the output image / video in pixels. |
138 * @param Cxe::AspectRatio Aspect ratio of image/video resolution. |
135 * @return Proposed best snapshot size. |
139 * @return Proposed best snapshot size. |
136 */ |
140 */ |
137 QSize CxeSnapshotControlPrivate::calculateSnapshotSize(const QSize &displaySize, const QSize &outputResolution) const |
141 |
138 { |
142 QSize CxeSnapshotControlPrivate::calculateSnapshotSize(const QSize& displaySize, Cxe::AspectRatio aspectRatio) const |
139 CX_DEBUG_ENTER_FUNCTION(); |
143 { |
140 CX_DEBUG(("CxeSnapshotControlPrivate - output resolution (%d,%d)", outputResolution.width(), outputResolution.height())); |
144 CX_DEBUG_ENTER_FUNCTION(); |
141 CX_DEBUG(("CxeSnapshotControlPrivate - display size (%d,%d)", displaySize.width(), displaySize.height())); |
145 CX_DEBUG(("CxeSnapshotControlPrivate - display size (%d,%d)", displaySize.width(), displaySize.height())); |
142 |
146 |
143 // Take resolution as reference for aspect ratio. |
147 // Take resolution as reference for aspect ratio. |
144 // Scale keeping aspect ratio to just fit display. |
148 // Scale keeping aspect ratio to just fit display. |
145 QSize size(outputResolution); |
149 QSize size; |
|
150 |
|
151 if (aspectRatio == Cxe::AspectRatio4to3) { |
|
152 size = ASPECT_RATIO_SIZE_4BY3; |
|
153 } else if (aspectRatio == Cxe::AspectRatio16to9) { |
|
154 size = ASPECT_RATIO_SIZE_16BY9; |
|
155 } else if (aspectRatio == Cxe::AspectRatio11to9) { |
|
156 size = ASPECT_RATIO_SIZE_11BY9; |
|
157 } |
146 size.scale(displaySize, Qt::KeepAspectRatio); |
158 size.scale(displaySize, Qt::KeepAspectRatio); |
147 CX_DEBUG(("CxeSnapshotControlPrivate - calculated size, (%d,%d)", size.width(), size.height())); |
159 |
148 size.setHeight(displaySize.height()); |
|
149 CX_DEBUG(("CxeSnapshotControlPrivate - adjusted final size, (%d,%d)", size.width(), size.height())); |
160 CX_DEBUG(("CxeSnapshotControlPrivate - adjusted final size, (%d,%d)", size.width(), size.height())); |
150 CX_DEBUG_EXIT_FUNCTION(); |
161 |
|
162 CX_DEBUG_EXIT_FUNCTION(); |
|
163 |
151 return size; |
164 return size; |
152 } |
165 } |
|
166 |
153 |
167 |
154 /*! |
168 /*! |
155 * Start getting snapshots from camera. |
169 * Start getting snapshots from camera. |
156 * Throws CxeException with CxeError::Id if error encountered. |
170 * Throws CxeException with CxeError::Id if error encountered. |
157 * @param size Size of the snapshot in pixels. |
171 * @param size Size of the snapshot in pixels. |
203 } |
217 } |
204 |
218 |
205 /*! |
219 /*! |
206 * Helper method for getting the snapshot. |
220 * Helper method for getting the snapshot. |
207 * Throws exception if fetching the snapshot fails. |
221 * Throws exception if fetching the snapshot fails. |
208 * @return QPixmap containing the snapshot. |
222 * @return QImage containing the snapshot. |
209 */ |
223 */ |
210 QPixmap CxeSnapshotControlPrivate::snapshot() |
224 QImage CxeSnapshotControlPrivate::snapshot() |
211 { |
225 { |
212 CX_DEBUG_ENTER_FUNCTION(); |
226 CX_DEBUG_ENTER_FUNCTION(); |
213 QPixmap pixmap; |
227 QImage image; |
214 |
228 |
215 #ifdef Q_OS_SYMBIAN |
229 #ifdef Q_OS_SYMBIAN |
216 TRAPD(status, { |
230 |
217 RArray<TInt> frameIndex; |
231 CFbsBitmap *snapshot = NULL; |
218 CleanupClosePushL(frameIndex); |
232 TRAPD(status, { |
219 |
233 RArray<TInt> frameIndex; |
220 MCameraBuffer &buffer(mDevice.cameraSnapshot()->SnapshotDataL(frameIndex)); |
234 CleanupClosePushL(frameIndex); |
221 // Make sure buffer is released on leave / exception. |
235 |
222 // Buffer is released once the cleanup item goes out of scope. |
236 MCameraBuffer &buffer(mDevice.cameraSnapshot()->SnapshotDataL(frameIndex)); |
223 CxeCameraBufferCleanup cleaner(&buffer); |
237 // Make sure buffer is released on leave / exception. |
224 |
238 // Buffer is released once the cleanup item goes out of scope. |
225 TInt firstImageIndex(frameIndex.Find(0)); |
239 CxeCameraBufferCleanup cleaner(&buffer); |
226 CFbsBitmap &snapshot(buffer.BitmapL(firstImageIndex)); |
240 |
227 |
241 TInt firstImageIndex(frameIndex.Find(0)); |
228 CleanupStack::PopAndDestroy(); // frameIndex |
242 snapshot = &buffer.BitmapL(firstImageIndex); |
229 |
243 |
230 TSize size = snapshot.SizeInPixels(); |
244 CleanupStack::PopAndDestroy(); // frameIndex |
231 TInt sizeInWords = size.iHeight * CFbsBitmap::ScanLineLength(size.iWidth, EColor16MU) / sizeof(TUint32); |
245 |
232 CX_DEBUG(("size %d x %d, sizeInWords = %d", size.iWidth, size.iHeight, sizeInWords )); |
246 TSize size = snapshot->SizeInPixels(); |
233 |
247 TInt sizeInWords = size.iHeight * CFbsBitmap::ScanLineLength(size.iWidth, EColor16MU) / sizeof(TUint32); |
234 TUint32 *pixelData = new (ELeave) TUint32[ sizeInWords ]; |
248 CX_DEBUG(("size %d x %d, sizeInWords = %d", size.iWidth, size.iHeight, sizeInWords )); |
235 // Convert to QImage |
249 |
236 snapshot.LockHeap(); |
250 CX_DEBUG(("Creating QImage")); |
237 TUint32 *dataPtr = snapshot.DataAddress(); |
251 image = QImage(size.iWidth, size.iHeight, QImage::Format_RGB32); |
238 memcpy(pixelData, dataPtr, sizeof(TUint32)*sizeInWords); |
252 |
239 snapshot.UnlockHeap(); |
253 // Convert to QImage |
240 |
254 snapshot->LockHeap(); |
241 CX_DEBUG(("Creating QImage")); |
255 const uchar *dataPtr = (const uchar*) snapshot->DataAddress(); |
242 QImage *snapImage = new QImage((uchar*)pixelData, size.iWidth, size.iHeight, |
256 uchar *dst = image.bits(); |
243 CFbsBitmap::ScanLineLength(size.iWidth, EColor16MU), |
257 memcpy(dst, dataPtr, image.numBytes()); |
244 QImage::Format_RGB32); |
258 snapshot->UnlockHeap(); |
245 |
259 |
246 pixmap = QPixmap::fromImage(*snapImage); |
260 }); |
247 delete [] pixelData; |
261 // We throw error with the Symbian error code if there was problems. |
248 delete snapImage; |
262 CxeException::throwIfError(status); |
249 }); |
263 |
250 // We throw error with the Symbian error code if there was problems. |
264 |
251 CxeException::throwIfError(status); |
265 #endif // Q_OS_SYMBIAN |
252 #endif // Q_OS_SYMBIAN |
266 |
253 |
267 CX_DEBUG_EXIT_FUNCTION(); |
254 CX_DEBUG_EXIT_FUNCTION(); |
268 return image; |
255 return pixmap; |
|
256 } |
269 } |
257 |
270 |
258 /*! |
271 /*! |
259 * Handle camera snapshot events. |
272 * Handle camera snapshot events. |
260 * @param id Event uid. |
273 * @param id Event uid. |