symba (779893), страница 39
Текст из файла (страница 39)
Mostplug-ins just read parameters during the synchronous part of theConvert() call, but it is better to be on the safe side.Setting up encoding parameters is quite easy in cases where theapplication is always encoding to the same destination image format. Itbecomes a little bit tricky when the destination image format may bechanged depending on some conditions as it would involve several ifstatements to create the encoding parameters.Unfortunately, the encoder parameter setup implementation does notallow the application to discover the set of supported parameters fora given plug-in.
One way of overcoming this limitation is to create asmany parameters as needed and pass them in. At the moment, Symbiansupplied plug-ins ignore any unknown parameters and encode the image;however this behavior is not documented and may change. It also meansthat non-Symbian plug-ins may behave differently.It is possible to ask an encoder plug-in to automatically generate athumbnail for the image being encoded:void CImageEncoder::SetThumbnail(TBool aDoGenerateThumbnail);Not all image formats support thumbnails.
What would happen if thismethod is used to enable thumbnail generation while a GIF image isbeing encoded, for example? Nothing, if the Symbian-supplied encoderplug-in is used. All Symbian-supplied encoder plug-ins ignore this call ifthumbnail generation is not supported.DISPLAYING IMAGES1816.3.3 Encoder Plug-ins Provided by SymbianSymbian supplies a number of CImageEncoder plug-ins in its referenceSDK (see Table 6.7). Device manufacturers are free to ship these plug-inswith their smartphones, replace them with their own specific versions orremove them (if they do not need them). There is no 1:1 correspondencebetween decoder and encoder plug-ins, as it is not always feasible tocreate certain image types on a smartphone.Table 6.7 Encoder Plug-insImage Format Encoder UIDNotesWindows bitmap (.bmp)KBMPEncoderImplementationUidValueThe 1, 4, 8, and 24 bpp formats are supported.RLE-encoded formats are not supported.
Device manufacturers usually use this plug-in without changes.Graphics Interchange Format (.gif)KGIFEncoderImplementationUidValueOnly the GIF87A format is supported. Neither maskencoding nor multiframe encoding is supported.Device manufacturers usually use this plug-in withoutchanges.JFIF/EXIF JPEG (.jpg)KJPGEncoderImplementationUidValueColor sampling can be monochrome, 420, 422 and444. Valid quality settings are between 1 and 100.Automatic generation of thumbnails and Exif metadatais supported.
Progressive and JPEG2000 formats arenot supported. Only interleaved color componentsare supported. Many device manufacturers replacethis plug-in with a hardware-accelerated version (theplug-in may be left but assigned a low priority).Symbian OS MBM (.mbm)KMBMEncodeDataUidValueEncoding to all valid Symbian display modes is supported. Device manufacturers usually use this plug-inwithout changes.Portable Network Graphics (.png)KPNGEncoderImplementationUidValueThe 1, 4, 8, and 24 bpp formats are supported. Threecompression levels are available: no compression,best speed, best compression.
Neither mask nor alphachannel encoding are supported. Device manufacturers usually use this plug-in without changes.6.4 Displaying ImagesThe CImageDisplay API can sometimes be seen as an analog of theCImageDecoder API; however it was designed to allow an applicationto easily display images, especially animated (multiframe) ones.182IMAGE CONVERSION LIBRARYThe CImageDisplay class8 is not a replacement for CImageDecoder, as it does not allow much access to the underlying image. Itabstracts an application from the image details and, where it is possibleto do so, from the plug-in capabilities as well.This API shares many design elements with CImageTransform (seeSection 6.5).
However, it does not force an API client to use active objectswhen performing image decoding. This does not mean that the frameworkitself uses additional operating system threads to decode an image in thebackground. Instead, the framework makes use of active objects whichoperate in the client thread. Rather than passing a TRequestStatus intothe framework, a client has to implement an observer interface throughwhich it is notified when the framework has completed an operation.The main advantages of using CImageDisplay for displaying images are:• Scaling and rotation are provided as a part of core CImageDisplayfunctionality; these features are limited only by the capabilities of thebitmap manipulation APIs (see Section 6.6).• All frame composition is done by the framework, so a client is providedwith a ready-to-display bitmap for each animation frame.• All the animation inter-frame delay processing is done by the framework, so a client is notified via the observer interface when a framehas to be displayed.• All the animation frames are owned by the framework, so a clientdoes not have to do resource management.Using a CImageDisplay object to display animated images shouldsave hundreds of lines of code, at the price of slightly reduced APIflexibility (i.e.
lack of access to low-level information about the imagebeing decoded) and support for transparent use of threads. Unlike in theCImageDecoder API, there is no threading support and the plug-ins arealways created in the client thread.The framework implementation requires its users to adhere to a particular pattern of calls. Figure 6.9 shows a typical sequence of calls whichan application should carry out in order to ‘play’ or display an image.The framework can be used in the same way to display a single-frameimage, which is treated as an animation with just one frame.Unlike CImageDecoder, CImageDisplay does not combine thecreation and plug-in loading phases.
Instead, a plug-in is not attempted tobe loaded until CImageDisplay::SetupL() has been called. A clienthas to issue several initialization calls and then call SetupL() to tell the8 Thisframework is not included in S60 3rd Edition SDKs.DISPLAYING IMAGES183«interface»CoeControl:MIclImageDisplayObserverApplication:CImageDisplayNewL(aObserver) :CImageDisplay∗{mandatory}{mandatory}{optional}SetImageSource(aSource)SetOptions(aOptions) :TIntSetDisplayMode(aDisplayMode)SetupL(){mandatory}RecommendedImageSizes() :const RImageSizeArray&{mandatory}SetSizeInPixels(aSize,aMaintainAspectRatio)SetSourceRect(aRect){optional}Play()loop[no error, more frames to decode]MiidoImageReady(aBitmap,aStatus,aUpdatedArea,aError)[no error]: DrawNow(aBitmap)[no error, more frames]: Play()MiidoImageReady(aBitmap,aStatus,aUpdatedArea,aError)Animation CompleteddeleteFigure 6.9 Typical sequence diagram for using CImageDisplayframework that a plug-in which matches the given parameters should beloaded.After successful completion of SetupL(), a client should performsome more animation setup based on the information about the imageexposed by the plug-in.
Once that setup is complete, the client has tocall CImageDisplay::Play() to start animation decoding. Then theclient has to yield back to the active scheduler (in the case of a UIapplication, that happens naturally once the current menu command hasbeen handled).The framework then begins calling the observer method (MiidoImageReady) for each animation frame when it is the right time to do so.184IMAGE CONVERSION LIBRARYInside the MiidoImageReady callback, a client should either draw thegiven bitmap or take a copy of its content (which is not recommended)and return as soon as possible.In the course of decoding, a client can stop the ‘playback’, callReset() and redo setup in order to reuse the same object for manyimages.
Figure 6.10 shows a diagram of the framework with possibletransitions between states. The framework will panic an application if ittries to bypass the state transitions.SetSourceXXX()ageRusPlae()eady()y()ConfiguredSetSourceXXX()ImPaReset()Reset()PausedReset()SetupL()Opened)et(sReFinished ProcessingProcessingPlay()StopPlay()PluginLoadedStopPlay()Figure 6.10CImageDisplay state diagramThe following code illustrates the use of CImageDisplay to playmultiframe images. It assumes that an image resides in a file and asks theframework to double (upscale) the size of the image.void CImageDisplayHandler::ConstructL(){User::LeaveIfError( iFs.Connect() );iImgDisplay = CImageDisplay::NewL(*this, iFs);}void CImageDisplayHandler::MiidoImageReady(const CFbsBitmap* /*aBitmap*/,TUint aStatus,const TRect& /*aUpdatedArea*/,TInt aError){TRANSFORMING IMAGES185if (aError != KErrNone){// the framework encountered an error during playback, so handle it.// NOTE: you cannot "delete" the object from within this callback}if ((aStatus & CImageDisplayPlugin::EStatusFrameReady) ==CImageDisplayPlugin::EStatusFrameReady){const CFbsBitmap* frame = NULL;const CFbsBitmap* mask = NULL;iImgDisplay->GetBitmap(frame, mask);// display these bitmaps}if ((aStatus & CImageDisplayPlugin::EStatusNoMoreToDecode) ==CImageDisplayPlugin::EStatusNoMoreToDecode){// we reached the end of the animation}else{// otherwise ask the framework to continue animationiImgDisplay->Play();}}void CImageDisplayHandler::PlayImageL(const TDesC& aFileName){// re-use the framework objectiImgDisplay->Reset();// Set the image source (to a file name, a handle or a memory buffer).// This is a mandatory calliImgDisplay->SetImageSource(TMMFileSource(aFileName));// Tell the framework to decode the main image (not a thumbnail)// and perform automatic rotation.
Note that either EOptionMainImage or// EOptionThumbnail has to be defined otherwise the framework will paniciImgDisplay->SetOptions(CImageDisplay::EOptionMainImage |CImageDisplay::EOptionAutoRotate);// Tell the framework to load a plug-iniImgDisplay->SetupL();// Retrieve the original image sizeTSize originalSize(iImgDisplay->RecommendedImageSizes()[0]);// Set the size to which the image is to be decoded.
It can be// virtually any size. This call must be made before Play()iImgDisplay->SetSizeInPixels(TSize(originalSize.iWidth*2,originalSize.iHeight*2));// start the animationiImgDisplay->Play();}6.5 Transforming ImagesThe image transformation API9 is designed to aid applications to transform images which are encoded in a format other than native bitmapformat. Native bitmaps can be efficiently transformed using the bitmap9 ThisAPI is not included in the S60 3rd Edition SDKs.186IMAGE CONVERSION LIBRARYtransformation API (see Section 6.6). The image transformation API isan extendable, plug-in-based framework, which shares many designprinciples with CImageDecoder.At the time of writing, CImageTransform was able to perform thefollowing operations:• image scaling• thumbnail addition/removal• Exif metadata editing.CImageTransform can be thought of as a processing unit thataccepts an image in a well-defined format and some setup parametersand produces an image in a well-defined image format as an output.6.5.1 Basic Use of CImageTransformThe following code example illustrates use of the CImageTransformAPI.void CImageTransformHandler::BeginTranformL(const TDesC& aFileName,CImageTransform::TOptions aTransformOpt,const TSize* aNewMainImageSize){// the framework allows object re-use, but we have to reset it firstiImgTransform->Reset();// set the source file nameiImgTransform->SetSourceFilenameL(aFileName);// Create a file name for the destination file.