examples/Multimedia/ICL/ICLExample/iclimageprocessorexample.cpp

Go to the documentation of this file.
00001 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
00002 // All rights reserved.
00003 // This component and the accompanying materials are made available
00004 // under the terms of "Eclipse Public License v1.0"
00005 // which accompanies this distribution, and is available
00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00007 //
00008 // Initial Contributors:
00009 // Nokia Corporation - initial contribution.
00010 //
00011 // Contributors:
00012 //
00013 // Description:
00014 // The code demonstrates Image Processor functionality
00015 //
00016 
00017 
00018 
00023 #include "iclexample.h"
00024 #include <imageprocessor/imageprocessor.h>
00025 #include <imageprocessor/imageprocessorobserver.h>
00026 #include <imageprocessor/imageprocessorinputinfo.h>
00027 #include <imageprocessor/imageprocessoroutputinfo.h>
00028 #include <imageprocessor/imageprocessoroverlay.h>
00029 #include <imageprocessor/imageprocessorpreview.h>
00030 #include <imageprocessor/imageprocessoreffect.h>
00031 #include <imageprocessor/imageprocessorprogressinfo.h>
00032 #include <capsimageprocessor/capsimageprocessorextension.h>
00033 
00034 using namespace ImageProcessor;
00035 
00040 class CImgProcessorObserverStub: public ImageProcessor::MImgProcessorObserver
00041         {
00042         public:
00043                 CImgProcessorObserverStub(CConsoleBase& aConsole) : iConsole(aConsole), 
00044                         iNumberOfDots(0), iCurrentIteration(0), iNumberOfIterations(0) {}
00045 
00046         public:
00047                 void ImageProcessorInitializingComplete(ImageProcessor::CImgProcessor& /*aImageProcessor*/, TInt aError)
00048                         {
00049                         iConsole.Printf(_L("\nImageProcessorInitializingComplete, aError = %d\n"), aError);
00050                         iCurrentIteration = 0;
00051                         iNumberOfIterations = 0;
00052                         iNumberOfDots = 0;
00053                         CActiveScheduler::Stop();
00054                         }
00055                 
00056                 void ImageProcessorPreviewInitializingComplete(ImageProcessor::CImgProcessor& /*aImageProcessor*/, TInt aPreviewId, TInt aError)
00057                         {
00058                         iConsole.Printf(_L("\nImageProcessorPreviewInitializingComplete, aPreviewId = %d, aError = %d\n"), aPreviewId, aError);
00059                         iCurrentIteration = 0;
00060                         iNumberOfIterations = 0;
00061                         iNumberOfDots = 0;
00062                         CActiveScheduler::Stop();
00063                         }
00064                 
00065                 void ImageProcessingComplete(ImageProcessor::CImgProcessor& /*aImageProcessor*/, TInt aError)
00066                         {
00067                         iConsole.Printf(_L("\nImageProcessingComplete, aError = %d\n"), aError);
00068                         iCurrentIteration = 0;
00069                         iNumberOfIterations = 0;
00070                         iNumberOfDots = 0;
00071                         CActiveScheduler::Stop();
00072                         }
00073                 
00074                 void ImageProcessorPreviewRenderingComplete(ImageProcessor::CImgProcessor& /*aImageProcessor*/, TInt aPreviewId, TInt aError)
00075                         {
00076                         iConsole.Printf(_L("\nImageProcessorPreviewRenderingComplete, aPreviewId=%d, aError=%d\n"), aPreviewId, aError);
00077                         iCurrentIteration = 0;
00078                         iNumberOfIterations = 0;
00079                         iNumberOfDots = 0;
00080                         CActiveScheduler::Stop();
00081                         }
00082                 
00083                 void ImageProcessorEvent(ImageProcessor::CImgProcessor& aImageProcessor, TInt /*aEventId*/, TUid /*aUid*/, TInt /*aId*/)
00084                         {
00085                         // We try to emulate a progress bar by printing out 
00086                         // a dot per one tenth of all iterations completed. 
00087                         // So ten dots are printed out when the processing is finished.
00088                         
00089                         TProgressInfo* progressInfo = NULL;
00090                         
00091                         // Get TProgressInfo interface to get progress information
00092                         TInt err = KErrNone;
00093                         TRAP(err, progressInfo = aImageProcessor.ProgressInfoL());
00094                         
00095                         // Get total number of iterations for the processing/rendering
00096                         if (iNumberOfIterations == 0) 
00097                                 {
00098                                 TRAP(err, iNumberOfIterations =  progressInfo->NumberOfIterationsL());
00099                                 }
00100 
00101                         // Get current iteration
00102                         TRAP(err, iCurrentIteration = progressInfo->CurrentIterationL());
00103                         
00104                         if (err == KErrNone) 
00105                                 {
00106                                 // Print out another dot if next one tenth is processed
00107                                 if (10 * iCurrentIteration > iNumberOfDots * iNumberOfIterations) 
00108                                         {
00109                                         iNumberOfDots++;
00110                                         iConsole.Printf(_L("."));
00111                                         }
00112                                 }
00113 
00114                         }
00115         private:
00116                 CConsoleBase& iConsole;
00117                 TInt iNumberOfDots;
00118                 TInt iCurrentIteration;
00119                 TInt iNumberOfIterations;
00120         };
00121 
00125 void CIclExample::BasicImageProcessingL()
00126         {
00127         CImgProcessorObserverStub observer(*iConsole);
00128         ImageProcessor::CImgProcessor* imageProcessor = ImageProcessor::CImgProcessor::NewL(iFs, observer);
00129         CleanupStack::PushL(imageProcessor);
00130         
00131         // Initialize the Image Processor instance. By default the initialization is asynchronous.
00132         // (It might take some time to load Image Processor plugin and initialize it).
00133         imageProcessor->InitializeL();
00134 
00135         // Wait for asynchronous callback
00136         CActiveScheduler::Start();
00137 
00138         // Set input and output images
00139         imageProcessor->SetInputL(KInputFileName, KImageTypeJPGUid);
00140         imageProcessor->SetOutputL(KOutputFileName, KImageTypeJPGUid);
00141                 
00142         // Get TOutputInfo interface
00143         TOutputInfo* outputInfo = imageProcessor->OutputInfoL();
00144 
00145         // Set 0.75 quality for the output image.
00146         // (Note. Default quality value for the output image is the same as for the input image.)
00147         TReal32 quality = 0.75f;
00148         outputInfo->SetJpegQualityL(quality);
00149 
00150         // Process the input image to the output image. 
00151         // The output image size is QVGA and the output image keeps the same aspect ratio as the input image.  
00152         imageProcessor->ProcessL(TSize(320, 240), ETrue);
00153 
00154         // Wait for asynchronous callback
00155         CActiveScheduler::Start();
00156 
00157         CleanupStack::PopAndDestroy(imageProcessor);
00158         }
00159 
00164 void CIclExample::BasicEffectImageProcessingL()
00165         {
00166         CImgProcessorObserverStub observer(*iConsole);
00167         ImageProcessor::CImgProcessor* imageProcessor = ImageProcessor::CImgProcessor::NewL(iFs, observer);
00168         CleanupStack::PushL(imageProcessor);
00169 
00170         // Initialize the Image Processor instance. By default the initialization is asynchronous.
00171         imageProcessor->InitializeL();
00172 
00173         // Wait for asynchronous callback
00174         CActiveScheduler::Start();
00175 
00176         imageProcessor->SetInputL(KInputFileName, KImageTypeJPGUid);
00177         imageProcessor->SetOutputL(KOutputWithBasicEffectFileName, KImageTypeJPGUid);
00178                 
00179         // The TOutputInfo interface is used to set quality and sampling scheme for JPEG output
00180         TOutputInfo* outputInfo = imageProcessor->OutputInfoL();
00181 
00182         // Set 0.75 quality for the output image.
00183         // (Note. Default quality value for the output image is the same as for the input image.)
00184         TReal32 quality = 0.75f;
00185         outputInfo->SetJpegQualityL(quality);
00186 
00187         // Get information about the input image
00188         TInputInfo* inputInfo = imageProcessor->InputInfoL();
00189         TSize inputSize = inputInfo->SizeL();
00190 
00191         // Define crop region - eighth size
00192         TRect cropRegion(inputSize.iWidth/4, inputSize.iHeight/4, inputSize.iWidth/2, inputSize.iHeight/2);
00193 
00194         // Apply crop gives a quarter size image
00195         imageProcessor->SetInputRectL(cropRegion);
00196 
00197         // Get TEffect interface for Mirror Left To Right effect. 
00198         // Note. All effects can be handled via generic TEffect interface. For more advanced functionality
00199         // the interface pointer must be cast to a derived effect interface.
00200         TEffect* effect = imageProcessor->EffectL(KEffectMirrorLeftToRightUid);
00201         
00202         // Standard sequence of function calls to apply the default behaviour for an effect 
00203         // is to simply call BeginL() and then EndL().
00204         effect->BeginL();
00205         effect->EndL();
00206 
00207         // Some effects do not have a default behaviour and need to use the specialized interface.
00208         TGeometricalOperation* operation = static_cast<TGeometricalOperation*>(imageProcessor->EffectL(KGeometricalOperationUid));
00209         operation->BeginL();
00210         operation->SetOperationL(ImageProcessor::CImgProcessor::EOperationRotate270);
00211         operation->EndL();
00212 
00213         // Process the input image to the output image. 
00214         // If an output size is not given then its size will be equal to the current input image after any cropping and 
00215         // geometrical operations are applied, so preserving the aspect ratio.
00216         // For this example the output size is (inputSize.iHeight/4, inputSize.iWidth/4)).   
00217         imageProcessor->ProcessL();
00218 
00219         // Wait for asynchronous callback
00220         CActiveScheduler::Start();
00221 
00222         CleanupStack::PopAndDestroy(imageProcessor);
00223         }
00224 
00228 void CIclExample::EffectImageProcessingWithUndoL()
00229         {
00230         CImgProcessorObserverStub observer(*iConsole);
00231         ImageProcessor::CImgProcessor* imageProcessor = ImageProcessor::CImgProcessor::NewL(iFs, observer);
00232         CleanupStack::PushL(imageProcessor);
00233         
00234         // Initialize the Image Processor instance. By default the initialization is asynchronous.
00235         // (It might take some time to load Image Processor plugin and initialize it).
00236         imageProcessor->InitializeL();
00237 
00238         // Wait for asynchronous callback
00239         CActiveScheduler::Start();
00240 
00241         imageProcessor->SetInputL(KInputFileName, KImageTypeJPGUid);
00242         imageProcessor->SetOutputL(KOutputWithUndoFileName, KImageTypeJPGUid);
00243                 
00244         // The TOutputInfo interface is used to set quality and sampling scheme for JPEG output
00245         TOutputInfo* outputInfo = imageProcessor->OutputInfoL();
00246 
00247         // Set 0.75 quality for the output image.
00248         // (Note. Default quality value for the output image is the same as for the input image.)
00249         TReal32 quality = 0.75f;
00250         outputInfo->SetJpegQualityL(quality);
00251 
00252         // The rotation effect can be used via derived interface only.
00253         TEffectRotation* rotationEffect = static_cast<TEffectRotation*>(imageProcessor->EffectL(KEffectRotationUid));
00254         rotationEffect->BeginL();
00255         rotationEffect->SetRotationL(ImageProcessor::TEffectRotation::ERotationScaleModeFitInside, 45.0f);
00256         rotationEffect->EndL();
00257 
00258         // Check if we can undo last applied effect
00259         if (imageProcessor->CanUndoL()) 
00260                 {
00261                 // Undo the effect
00262                 imageProcessor->UndoL();                
00263                 }
00264 
00265         // Process the input image to the output image. 
00266         imageProcessor->ProcessL();
00267 
00268         // Wait for asynchronous callback
00269         CActiveScheduler::Start();
00270 
00271         // resultant image looks similar and has same image size as the input image but has some differences due to quality settings.
00272         CleanupStack::PopAndDestroy(imageProcessor); 
00273         }
00274 
00278 void CIclExample::EffectImageProcessingWithPreviewL()
00279         {
00280         CImgProcessorObserverStub observer(*iConsole);
00281         ImageProcessor::CImgProcessor* imageProcessor = ImageProcessor::CImgProcessor::NewL(iFs, observer);
00282         CleanupStack::PushL(imageProcessor);
00283         
00284         // Initialize the Image Processor instance. By default the initialization is asynchronous.
00285         // (It might take some time to load Image Processor plugin and initialize it).
00286         imageProcessor->InitializeL();
00287 
00288         // Wait for asynchronous callback
00289         CActiveScheduler::Start();
00290 
00291         // Initialize the list of images filenames
00292         const TDesC* filenames[4] = 
00293                 { 
00294                 &KInputFileName01, 
00295                 &KInputFileName02, 
00296                 &KInputFileName03, 
00297                 &KInputFileName04
00298                 };
00299 
00300         // Initialize the list of bitmaps filenames
00301         const TDesC* bitmapsnames[4] = 
00302                 { 
00303                 &KOutputBitmapFileName01, 
00304                 &KOutputBitmapFileName02, 
00305                 &KOutputBitmapFileName03, 
00306                 &KOutputBitmapFileName04
00307                 };
00308         
00309         // Create the output bitmap for the preview.
00310         // In this case the output bitmap should be considered as a offscreen buffer 
00311         CFbsBitmap* previewBitmap = new (ELeave) CFbsBitmap();
00312         previewBitmap->Create(TSize(320,240), EColor64K);
00313 
00314         CleanupStack::PushL(previewBitmap);
00315 
00316         // Define preview id for the preview
00317         const TInt previewId = 1;
00318 
00319         // Get TPreview interface using preview id
00320         TPreview* preview = imageProcessor->PreviewL(previewId);
00321         
00322         // Set all image processor operations including preview rendering to be synchronous.
00323         // The preview rendering should be reasonably quick so it is preferable to use
00324         // the option here and get better performance over asynchronous operations.
00325         // No callbacks to an observer are made in this case.
00326         imageProcessor->SetOptionsL(ImageProcessor::CImgProcessor::EOptionSyncProcessing);
00327         
00328         // Create a blank input and set up a chain of the effects before rendering the first preview.
00329         imageProcessor->CreateInputL(TSize(320, 240),  TRgb(0, 0, 0));
00330         
00331         // Initialize the preview
00332         preview->InitializeL();
00333 
00334         // Set output for the preview. 
00335         preview->SetOutputL(*previewBitmap);
00336 
00337         // Get sharpness effect
00338         TEffect* effect=imageProcessor->EffectL(KEffectSharpnessUid);
00339 
00340         // Apply default level of sharpness
00341         effect->BeginL();
00342         effect->EndL();
00343 
00344         // Get color boost effect
00345         effect = imageProcessor->EffectL(KEffectColorBoostUid);
00346 
00347         // Apply default level of color boost
00348         effect->BeginL();
00349         effect->EndL();
00350 
00351         // Get white balance effect
00352         effect = imageProcessor->EffectL(KEffectWhiteBalanceUid);
00353         
00354         // Apply default white balance 
00355         effect->BeginL();
00356         effect->EndL();
00357 
00358         // Go through the images and render the preview for each of them
00359         for (TInt i = 0; i < 4; i++) 
00360                 {
00361                 imageProcessor->SetInputL(*filenames[i]);
00362                 preview->RenderL();             
00363 
00364                 // Here a code to update the screen using the preview bitmap can be placed
00365                 // In our case we just save the bitmap.
00366                 previewBitmap->Save(*bitmapsnames[i]);
00367                 }
00368 
00369         CleanupStack::PopAndDestroy(2,imageProcessor); //previewBitmap imageProcessor
00370         }
00371 
00376 void CIclExample::EffectImageProcessingWithOverlayL()
00377         {
00378         CImgProcessorObserverStub observer(*iConsole);
00379         ImageProcessor::CImgProcessor* imageProcessor = ImageProcessor::CImgProcessor::NewL(iFs, observer);
00380         CleanupStack::PushL(imageProcessor);
00381         
00382         // Initialize the Image Processor instance. By default the initialization is asynchronous.
00383         // (It might take some time to load Image Processor plugin and initialize it).
00384         imageProcessor->InitializeL();
00385 
00386         // Wait for asynchronous callback
00387         CActiveScheduler::Start();
00388 
00389         // Set input and output files 
00390         imageProcessor->SetInputL(KInputFileName, KImageTypeJPGUid);
00391         imageProcessor->SetOutputL(KOutputWithOverlayFileName, KImageTypeJPGUid);
00392 
00393         // Create the output bitmap for the preview.
00394         CFbsBitmap* previewBitmap = new (ELeave) CFbsBitmap();
00395         previewBitmap->Create(TSize(320,240), EColor64K);
00396 
00397         CleanupStack::PushL(previewBitmap);
00398 
00399         // Define preview id for the preview
00400         const TInt previewId = 1;
00401 
00402         // Get TPreview interface using preview id
00403         TPreview* preview = imageProcessor->PreviewL(previewId); 
00404         
00405         // Set all image processor operation like preview rendering to be synchronous
00406         // The preview rendering should be reasonably quick so it is preferable to use
00407         // the option here.
00408         imageProcessor->SetOptionsL(ImageProcessor::CImgProcessor::EOptionSyncProcessing);
00409         
00410         // Initialize the preview
00411         preview->InitializeL();
00412         
00413         // Set output for the preview. 
00414         preview->SetOutputL(*previewBitmap);
00415 
00416         // we can check what this looks like by rendering to the preview
00417         preview->RenderL();
00418 
00419         TPoint overlayPosition(0,0);
00420 
00421         // Get preview canvas rectangle 
00422         TRect canvasArea = preview->CanvasAreaL();
00423         
00424         // Set overlay position to the center of the preview canvas area        
00425         overlayPosition.iX = (canvasArea.iBr.iX - canvasArea.iTl.iX) / 2;
00426         overlayPosition.iY = (canvasArea.iBr.iY - canvasArea.iTl.iY) / 2;
00427         
00428         // Convert the preview canvas coordinates to the input current coordinates  
00429         TPoint tmp(0, 0);
00430         preview->CanvasToCurrentCoordL(overlayPosition, tmp);
00431         overlayPosition = tmp;
00432          
00433         // Get TOverlay interface
00434         TOverlay* overlay = imageProcessor->OverlayL();
00435         
00436         // Begin the overlay with a overlay file
00437         overlay->SetInputL(KInputOverlayFileName, KImageTypePNGUid);
00438         overlay->BeginL();
00439 
00440         // Set overlay with 1.0 x/y scale (un-scaled), position at the center of the preview canvas, 0.0 angle (no rotation)
00441         overlay->SetL(1.0f, 1.0f, overlayPosition, 0.0f);
00442 
00443         // we can check what this looks like by rendering to the preview
00444         preview->RenderL();
00445         // save the content of the preview bitmap to check the result
00446         previewBitmap->Save(KOutputBitmapFileName01);
00447 
00448         // We can then double the size of the overlaid, rotate it 45 degrees clockwise 
00449         // and move it down ten screen pixels.
00450 
00451         // Double the size of the overlay 
00452         TReal32 overlayScaleX = 0.0f;
00453         TReal32 overlayScaleY = 0.0f;
00454         overlay->GetScaleL(overlayScaleX, overlayScaleY);
00455 
00456         overlayScaleX *= 2.0f;
00457         overlayScaleY *= 2.0f;
00458 
00459         TReal32 overlayAngle = overlay->AngleL();
00460 
00461         // Rotate the overlay 45 degrees 
00462         overlayAngle += 45.0f;
00463         if (overlayAngle >= 360.0f)
00464                 {
00465                 overlayAngle = overlayAngle - 360.0f;
00466                 }
00467 
00468         // Move down the position of the overlay 10 screen pixels
00469         overlayPosition = overlay->PositionL();
00470         overlayPosition.iY += 10;
00471 
00472         // Set overlay with new parameters
00473         overlay->SetL(overlayScaleX, overlayScaleY, overlayPosition, overlayAngle);
00474 
00475         // Apply overlay parameters and finish with overlay
00476         overlay->EndL();
00477 
00478         preview->RenderL();
00479 
00480         //save the content of the preview bitmap to check the result
00481         previewBitmap->Save(KOutputBitmapFileName02);
00482 
00483         // Restore default asyncronous processing
00484         imageProcessor->SetOptionsL(imageProcessor->Options() ^ ImageProcessor::CImgProcessor::EOptionSyncProcessing);
00485         
00486         // Process the input image to the output image. 
00487         imageProcessor->ProcessL();
00488 
00489         // Wait for asynchronous callback
00490         CActiveScheduler::Start();
00491         
00492         CleanupStack::PopAndDestroy(2,imageProcessor); //previewBitmap imageProcessor
00493         }
00494         
00501 void CIclExample::ImageProcessingWithSpmoL()
00502         {
00503         CImgProcessorObserverStub observer(*iConsole);
00504         ImageProcessor::CImgProcessor* imageProcessor = ImageProcessor::CImgProcessor::NewL(iFs, observer);
00505         CleanupStack::PushL(imageProcessor);
00506         
00507         // Initialize the Image Processor instance. By default the initialization is asynchronous.
00508         // (It might take some time to load Image Processor plugin and initialize it).
00509         imageProcessor->InitializeL();
00510 
00511         // Wait for asynchronous callback
00512         CActiveScheduler::Start();
00513 
00514         // Set input image. This one does not have Spmo, but it could have.
00515         imageProcessor->SetInputL(KInputFileName, KImageTypeJPGUid);
00516         imageProcessor->SetOutputL(KOutputWithSpmoFileName, KImageTypeJPGUid);
00517 
00518         // transfer exif from the input (this is not mandatory)
00519         imageProcessor->SetOptionsL(ImageProcessor::CImgProcessor::EOptionExifMetadataProcessing);
00520 
00521         // To access Spmo functionality it is necessary to get Caps image processor extension interface @publishedpartner.
00522         TCapsImageProcessorExtension* extension = static_cast<TCapsImageProcessorExtension*>(imageProcessor->Extension(KCapsImageProcessorExtensionUid));
00523 
00524         // Set add Spmo to the output. The Spmo will be optimized for preview at QVGA screen size.
00525         // The code below will be commented in when DTW-MM00213 is fixed
00526     extension->SetAddSpmoToOutputL(ETrue, TSize(320, 240));
00527 
00528         // it is not possible to apply effects AND set Speedview object to the output
00529         
00530         // Process the input image to the output image. 
00531         imageProcessor->ProcessL();
00532 
00533         // Wait for asynchronous callback
00534         CActiveScheduler::Start();
00535 
00536         CleanupStack::PopAndDestroy(imageProcessor);    
00537         }
00538 

Generated on Thu Jan 21 10:32:59 2010 for TB10.1 Example Applications by  doxygen 1.5.3