symba (779893), страница 14
Текст из файла (страница 14)
No further action is required by the application.DISPLAYING THE VIEWFINDER45Note that the direct screen access handles the visible region of thescreen – focus loss won’t stop the viewfinder if it is partially visible.This viewfinder mode can be more efficient than the bitmap-basedmode as it allows optimization of the path between the camera hardwareand the LCD controller (e.g.
often the YUV to RGB conversion and scalingcan take place in hardware). However, until recently, this mode has notbeen supported by S60 devices.3.4.2 Bitmap-based ViewfinderWhen a bitmap-based viewfinder is active, the camera passes bitmaps tothe application at regular intervals, and the application draws them onthe screen as appropriate.
The bitmaps are passed at a rate fast enough toensure a smooth viewfinder display. This will generally be less efficientthan using the direct screen viewfinder (when available), but it allows theclient to process the image for a computer vision application or game. (Forexample, one could use it with Nokia Research Center’s free computervision library2 to do feature recognition or motion detection.)To start the bitmap-based viewfinder, we use the following method:virtual void StartViewFinderBitmapsL(TSize& aSize);This method requires a single TSize parameter that determines thesize of the bitmap that we receive. It should be set to the size of screenarea into which we intend to draw the viewfinder.Following this, bitmaps are passed to us via one of the followingcallback methods;• ViewFinderReady(MCameraBuffer& aCameraBuffer,TInt aError) – This method is called when we use MCameraObserver2.
The bitmap is represented by class MCameraBufferand a CFbsBitmap to display can be retrieved from this class usingthe BitmapL() method. The MCameraBuffer is capable of encapsulating several frames which may be encoded; for a viewfinder,you should expect a single, unencoded frame in the form of aCFbsBitmap instance.• ViewFinderFrameReady(CFbsBitmap& aFrame) – This method is called when we use MCameraObserver.
The bitmap passed issimply a CFbsBitmap which can be drawn to the screen in the usualway. Note that, when using this method, the viewfinder frame mustbe drawn in the callback or the bitmap must be copied for later use.Once the callback returns, the API reuses the bitmap. Therefore if wetry to use the bitmap after that stage, we see tearing on the viewfinder.2 research.nokia.com/research/projects/nokiacv/index.html .46THE ONBOARD CAMERATRect screenRect = iAppView->Rect();TSize size = screenRect.Size();TCameraInfo info;iCamera->CameraInfo(info);if (info.iOptionsSupported & TCameraInfo::EViewFinderDirectSupported){iCamera->StartViewFinderDirectL(iCoeEnv->WsSession(),*iCoeEnv->ScreenDevice(),*iAppView->DrawableWindow(),screenRect);}else if (info.iOptionsSupported &TCameraInfo::EViewFinderBitmapsSupported){iCamera->StartViewFinderBitmapsL(size);}3.5 Capturing Still ImagesImage capture involves transferring the current image from the camerato the client.
Before a still image can be captured, we should query thecapabilities of the camera in use. There are two parameters that need tobe set based on the capabilities: the format of the captured image and itssize.3.5.1 Selecting the Image FormatThe formats that are supported are determined by TCameraInfo::iImageFormatsSupported. This is a bitfield of values from the enumeration CCamera::TFormat. When using cameras that support anumber of formats, we need to choose the format most suitable for ourapplication.CCamera::TFormat iFormat;TInt iSizeIndex;// Initial camera querying to get supported capture sizesvoid CCameraDemoAppUi::SelectCaptureModeL(CCamera::TFormat aFormat){iFormat = aFormat;//iSizeArray is defined elsewhere as RArray<TSize>for (TInt i=0; i<iInfo.iNumImageSizesSupported; ++i){TSize size;iCamera->EnumerateCaptureSizes(size, i, iFormat);iSizeArray.AppendL(size);}// SelectBestSize() looks through the list of supported sizes for the// most appropriate for the application e.g.
does it want the highest// resolution photo or does it want one that matches the display size?CAPTURING STILL IMAGES47iSizeIndex = SelectBestSize(iSizeArray);iCamera->PrepareImageCaptureL(iFormat, iSizeIndex);}// called to capture the imagevoid CCameraDemoAppUi::CaptureImage(){iCamera->CaptureImage();}The following formats may be supported:• EFormatJpeg and EFormatExif: these are encoded formats thatneed decoding before they can be displayed on the screen. The dataarrives encoded in a descriptor and the ICL framework is used todecode the data (see Chapter 6).• EFormatFbsBitmapColorXxx: these are uncompressed formatsin which the captured image is represented by a CFbsBitmap object.• EFormatXxBitRGBXxx and EFormatYUVXxx: these are raw dataformats, the characteristics of which are determined by the exactformat; the data arrives in a descriptor.The formats supported by a camera may be influenced by the resolutionof that camera.
High-resolution cameras are likely to present the imagedata in a compressed format, as the memory required to store the imagein its uncompressed form will be too great.Once we have selected a format to use, we can enumerate the capturesizes that are supported for that format. The number of image sizes supported is in TCameraInfo::iNumImageSizesSupported.
The sizesthemselves are returned by CCamera::EnumerateCaptureSizes()method.3.5.2 Preparing for Image CaptureBefore we can capture an image, we need to prepare the CCameraobject using the PrepareImageCaptureL() method. This allows thecamera subsystem to allocate any memory necessary and perform anyother setup required to capture an image; it must be called at least oncebefore requesting images.
If images are being captured in response touser input, you should prepare the camera in advance to minimize thedelay when capture is performed.iCamera->PrepareImageCaptureL(aFormat, aSizeIndex);The parameter aSizeIndex is the index of capture size that you wishto use; it corresponds to the aSizeIndex parameter of the EnumerateCaptureSizes() method.48THE ONBOARD CAMERAAfter a successful call to PrepareImageCaptureL(), the camera isready to start capturing images. Note that:• Image settings should be used only for capturing images; for videocapture, the camera should be prepared separately (see Section 3.6).• It is valid to prepare the camera for image capture and for videocapture in any order preceding the image capture.• Image capture cannot take place while video capture is active.3.5.3 Capturing an ImageImage capture is an asynchronous operation.
It is instantiated simply bymaking a call to the CaptureImage() method:iCamera->CaptureImage();After we call the above method, we receive a callback to the MCameraObserver2::ImageBufferReady() method:void CCameraAppUi::ImageBufferReady(MCameraBuffer& aCameraBuffer,TInt aError){if (aError == KErrNone){// use the image}else{// handle error}}Note that the viewfinder is not automatically stopped when an imageis captured. It is the responsibility of the client to stop the viewfinder anddisplay the captured image.We may want to capture more than one image; in that case, we cancall the CaptureImage() method again, however we must not callCaptureImage() again before:• We receive the ImageBufferReady() callback.• We cancel the ongoing image capture by calling CancelImageCapture().The image is encapsulated by the class MCameraBuffer, which is alsoused when receiving images from the viewfinder.
The MCameraBufferCAPTURING VIDEO49class can store image data in a number of ways and can store multipleframes. When capturing a still image, this class stores a single frame ofthe requested format.As mentioned above, we can choose the image format of the image weare capturing.
If we requested an EFormatFbsBitmapColorXxx whenwe configured the image capture, the MCameraBuffer::BitmapL()method returns a handle to the CFbsBitmap containing the image data. Ifwe requested an EFormatJpeg or an EFormatExif, the descriptor canbe decoded to a CFbsBitmap using CImageDecoder (see Chapter 6)or the data can be written directly to a JPEG file.For other formats where the data is presented in a descriptor, the datacan be accessed using the MCameraBuffer::DataL() method. Theinterpretation of this data depends on the format that we requested.Note that once we have finished processing an MCameraBufferobject, we must call its Release() method to avoid memory leaks.This releases the memory used and allows it to be reused by the camerasubsystem.Some camera implementations are able to store the data in a sharedchunk. In this case, the ChunkL() and ChunkOffsetL() methodsreturn details of it.If we are working on a phone that only supports MCameraObserverand does not support MCameraObserver2, the equivalent callback is:MCameraObserver::ImageReady(CFbsBitmap* aBmp, HBufC8* aData, TInt aError)The CFbsBitmap and HBufC8 pointers can be considered equivalent to the objects returned by MCameraBuffer::BitmapL() andMCameraBuffer::DataL(), respectively.
Only one of them is valid,as determined by the image format in use. In this case, when we finishusing the pointer, we need to delete it in order to avoid a memoryleak.3.6 Capturing VideoVideo capture involves transferring image frames from the camera to theclient. Before video can be captured, we should query the capabilities ofthe camera in use. There are three parameters that need to be set basedon the capabilities: format, size, and rate. You can also set the number ofbuffers to use and the number of frames per buffer.3.6.1 Selecting the Video Format, Size and RateThe video formats that are supported are determined by TCameraInfo::iVideoFrameFormatsSupported.
This is a bitfield of values from the50THE ONBOARD CAMERAenumeration CCamera::TFormat. When using cameras that supporta number of formats, we need to choose the format most suitable forour application. For example, you would want to choose an uncompressed format if you wished to do some sort of processing on the videoframes or compress them to another format, but might choose JPEG compressed frames if you wanted to stream them to a PC or another device.Video formats are read in the same way as the still image formats (seeSection 3.5).Once we have selected a format to use, we can enumerate the videocapture sizes that are supported for that format.