Adding Effects And Filters Guide

This document gives you more information about the image effects and filters.

Purpose

The purpose of this guide is to show you how to implement different image effects and filters using Image Processor.

Introduction

Adding effects to an image with Image Processor is very simple.

Effects are applied in the order they are inserted in a image. Note: The result from rendering an image can be different depending on the order the effects are applied to an image.

The code example below shows an implementation in the order: crop, mirror, and 90 degree rotation.


// Get TInputInfo interface
TInputInfo* inputInfo = imageProcessor->InputInfoL();
// Get the input image size
TSize inputSize = inputInfo->SizeL();

// Define crop region
TRect cropRegion(inputSize.iWidth / 4, inputSize.iHeight / 4, inputSize.iWidth / 2, inputSize.iHeight /2);

// Apply crop
imageProcessor->SetInputRectL(cropRegion);

// Get TEffect interface for Mirror Left To Right effect. 
// Note. All effects can be handled via generic TEffect interface. For more advanced functionality
// the interface pointer must be cast to a derived effect interfece.
TEffect* effect = imageProcessor->EffectL(KEffectMirrorLeftToRightUid);

// Standard sequence of function calls to apply any effect. 
// The effect must be started with BeginL() and finished with EndL() functions calls.
effect->BeginL();
effect->EndL();

// As non-standard effect geometrical operation can be used via derived interface only.
TGeometricalOperation* operation = static_cast<TGeometricalOperation*>(imageProcessor->EffectL(KGeometricalOperationUid));
operation->BeginL();
operation->SetOperationL(ImageProcessor::CImgProcessor::EOperationRotate270);
operation->EndL();

Undo

Image Processor has a built-in undo mechanism, which removes the last added effect or operation on the undo stack. Parameter changes are not added to the undo stack. There is an unlimited number of undo steps and you can check if an undo operation is possible.

The code example below shows the implementation the ImageProcessor::CImageProcessor::UndoL() function:


TEffectRotation* rotationEffect = static_cast<TEffectRotation*>(imageProcessor->EffectL(KEffectRotationUid));
rotationEffect->BeginL();
rotationEffect->SetRotationL(ImageProcessor::TEffectRotation::ERotationScaleModeFitInside, 45.0f);
rotationEffect->EndL();

// Check if we can undo last applied effect
if (imageProcessor->CanUndoL()) 
{
    // Undo the effect
    imageProcessor->UndoL();
}

Adjustable generic effects

Those imaging effects that have variable strengths or settings to choose from are called adjustable generic effects. These effects each have three related functions:

  • The ImageProcessor::TEffect::BeginL() function is used to initiate the adjustable generic effect.

    Any function calls from Image Processor operations are disabled until the EndL() function is called. For example when you try to apply another effect, this cause a leave KErrNotReady.

    For example, if you want to invoke an UndoL() call, Image Processor operations are blocked between BeginL() and thecorresponding EndL() call. An UndoL() call can be invoked after an EndL() call. This will cancel the effects applied between the last BeginL() and EndL() calls.

  • The ImageProcessor::TEffect::SetLevelL() function is used to set the parameters of the current adjustable effect.

    For example, when you want to change the parameters of the effect, you must call the ImageProcessor::TEffect::SetLevelL() function to set the parameters of the current adjustable effect.

  • The ImageProcessor::TEffect::EndL() function is used to end the current adjustable effect.

    For example, when you are satisfied with the result of the effect, you must call ImageProcessor::TEffect::EndL() to complete the current adjustable effect.

    Note: If you are not satisfied with the result of the effect, you must call the EndL() function of the current generic effect followed by a call to the UndoL() function.

The code example below shows how to use an adjustable begin-end effect:


// Get sharpness effect
TEffect* effect=imageProcessor->EffectL(KEffectSharpnessUid);

// Apply default level of Sharpness
effect->BeginL();
effect->EndL();

Working with preview

Most mobile imaging applications render full-resolution images twice:

  1. for a preview on the screen

  2. for the rendering of the output image.

To make the render operation into a simple function, you must call the ImageProcessor::TPreview function.

The ImageProcessor::TPreview function is an interface that describes the preview identified by the preview ID. The interface is initialized by specifying an output Symbian bitmap or pixel buffer (image frame) by calling ImageProcessor::TPreview::SetOutput().

You can use the preview for the zoom and pan effects:


void TPreview::SetZoomL(TReal32 aZoom);
void TPreview::SetPanL(TReal32 aPanX, TReal32 aPanY);
TReal32 TPreview::ZoomL() const;
void TPreview::PanL(TReal32& aPanX, TReal32& aPanY) const;

The TReal32 of pan effect ranges from -1.0 to 1.0 and the TReal32 of zoom effect ranges from 1.0x to TReal32 maximum value.

Note: The zoom and pan effects only affect the preview. When rendering the original image, these changes are ignored.

Changing the input

The source image can be changed by calling the ImageProcessor::CImgProcessor::SetInputL() function without creating a new Image Processor instance. ImageProcessor::CImgProcessor::SetInputL() can be used when displaying thumbnails or when choosing between different overlay graphics. The image source can freely be switched between file, buffer, bitmap and a background colour.

The code example below illustrates the chain of effects applied to a number of images and rendered to screen.


    // Get white balance effect
    effect = imageProcessor->EffectL(KEffectWhiteBalanceUid);
    
    // Apply default white balance 
    effect->BeginL();
    effect->EndL();

    // Go through the images and render the preview for each of them
    for (TInt i = 0; i < 4; i++) 
        {
        imageProcessor->SetInputL(*filenames[i]);
        preview->RenderL();
  }

Image information

Image Processor has functionality to get information about the source image. This information can be used for display in a file browser or to verify the correct capabilities that are available for a specific processing task.

First, a pointer to ImageProcessor::TInputInfo() interface must be obtained from the active Image Processor instance. To extract the information, the following functions are called:


TSize TInputInfo::SizeL() const; 
void TInputInfo::FormatL(TUid& aFormat, TUid& aSubFormat) const;
TDisplayMode TInputInfo::DisplayModeL() const; 
TUid TInputInfo::ImageFrameFormatL() const; 
TUid TInputInfo::SamplingL() const; 
TUint32 TInputInfo::BitsPerPixelL() const; 
TBool TInputInfo::IsProgressiveL() const; 
TBool TInputInfo::IsInterlacedL() const; 
TBool TInputInfo::HasAlphaL() const;

Coordinates and areas

Image Processor uses a number of different coordinate systems to cope with the translation from the preview image to the input image.

In this section the following concepts are introduced:

Input images

A coordinate system is the region within which a given set of coordinates are relevant. In many scenarios, you will need to provide coordinate information to Image Processor. This information is ambiguous without additional handling to make the coordinates apply to a specific coordinate system.

An area defines the dimensions of a region. Image data can change form and scale during the editing session, which means that a set of areas with different dimensions can exist throughout the chain of operations.

All imaging sessions use a source image as a base. The source image represents the source coordinate system and the source area. The source coordinate system is not public since it has no relevance to the user. The source coordinate system starts at the top left corner of the source image and expands downwards along the y-axis and to the right along the x-axis. The source area size is public, however, and can be queried through the ImageProcessor::CImgProcessor::CurrentSizeL() function.

Geometry and orientation effects

Applying geometry effects and orientation effects to an input image is usually a chain process. When all effects have been applied, the resulting image may differ in geometry from the original source image. Hence, the resulting image defines a new area called the current area and a new coordinate system called the current coordinate system. Both of these are public and can be queried through the Image Processor. The current coordinate system starts at the top left corner of the image and expands downwards along the y-axis and to the right along the x-axis.

Previews

You can make use of one or more previews when processing an image. A preview defines the region on which the image is shown. A preview introduces the preview area and the preview coordinate system, both of which are public. The preview coordinate system starts at the top left corner of the screen and expands downwards along y-axis and to the right along x-axis.

Use ImageProcessor::TPreview::PreviewToCurrentCoordL() to perform coordinate conversion and ImageProcessor::TPreview::SizeL() to get the size of the preview area.

To convert between preview coordinates and current coordinates use the ImageProcessor::TPreview::PreviewToCurrentCoordL(const TPoint&) function. To convert between canvas coordinates to current coordinates use the ImageProcessor::TPreview::CanvasToCurrentCoordL() function.

It can be useful to know the current size of the session image, that is, the size of the image after any effects and cropping have been applied, by using the ImageProcessor::CImgProcessor::CurrentSizeL() function.

Preview canvases

Each preview contains a sub-region called the canvas. When the resulting image is scaled to fit the preview area, while preserving aspect ratio, the actual image data will not cover the entire screen and the areas outside the image are filled with a background colour. The area containing the image data is always referred to as the canvas. A canvas introduces the canvas area and the canvas coordinate system, both of which are public. The canvas coordinate system starts at the top left corner of the canvas and expands downwards along the y-axis and to the right along the x-axis.

Use the ImageProcessor::TPreview::CanvasToCurrentCoordL() to perform coordinate conversion andImageProcessor::TPreview::CanvasAreaL() function to return the size and location of the canvas area.

Zoom and Pan settings

Zoom and Pan settings do not introduce their own areas or coordinate systems. In this regard, Zoom and pan are equivalent to a preview.

Overlay images

Overlay images define their own overlay coordinate system and overlay area. The coordinate system of an overlay image is public. The overlay coordinate system and overlay are rarely used since they are not treated as separate objects once they are applied to the source image. The overlay is treated as part of the original image data after insertion.

However, the coordinate system of an overlay image is relevant for defining its anchor point to the source image. The overlay area can be queried from Image Processor instances that expose overlay operations. The overlay coordinate system starts at the centre of the overlay image and expands to the left along the negative side of the y-axis, upwards along the negative side of the x-axis, to the right along the x-axis and downwards along the y-axis.

Applying overlay and border effects

It is possible to add borders (frames) and overlays to your input image. For example, you might want to add a logo to an image or add a pair of sunglasses to a picture. To use a border effect, call ImageProcessor::CImgProcessor::EffectL(KEffectBorderUid).

Border images are images with alpha channels. The border is automatically stretched to fit the input image.

To use overlay effect, call ImageProcessor::CImgProcessor::OverlayL().

There are two ways to insert an overlay to an image, either from a file or from memory. If you load the overlay from a file, both PNG and JPEG are accepted, but you will only have the transparency option if you use a PNG image. The overlay is managed through the interface ImageProcessor::TOverlay.

You can specify the position, the scale, and the angle of the overlay. The position must be given in current coordinates. The scale ranges from 0.0 to infinity, where 1.0 represent no scaling. The angle ranges from 0.0 degrees to 360.0 degrees. To begin inserting the overlay the ImageProcessor::TOverlay::BeginL() function must be called. The code example below illustrates the scale effect and the angle of the overlay effect.

When the overlay is in place you must call ImageProcessor::TOverlay::EndL() to conclude the overlay.

The code examples below describe some common scenarios:

  • You want to insert an overlay image in the centre of the image you see on the screen. The scale is set to 1.0 and the angle is set to 0 degrees. It is crucial to distinguish between canvas coordinates and current coordinates.

  • After the overlay is started you want to double its size, rotate it 45 degrees clockwise, and move it down ten screen pixels.


    TPoint overlayPosition(0,0);

    // Get preview canvas rectangle 
    TRect canvasArea = preview->CanvasAreaL();
        
    // Set overlay position to the center of the preview canvas area     
    overlayPosition.iX = (canvasArea.iBr.iX - canvasArea.iTl.iX) / 2;
    overlayPosition.iY = (canvasArea.iBr.iY - canvasArea.iTl.iY) / 2;
    
    // Convert the preview canvas coordinates to the input current coordinates  
    TPoint tmp(0, 0);
    preview->CanvasToCurrentCoordL(overlayPosition, tmp);
    overlayPosition = tmp;
     
    // Get TOverlay interface
    TOverlay* overlay = imageProcessor->OverlayL();
    
    // Begin the overlay with a overlay file
    overlay->SetInputL(KInputOverlayFileName, KImageTypePNGUid);
    overlay->BeginL();

    // Set overlay with 1.0 x/y scale (un-scaled), position at the center of the preview canvas, 0.0 angle (no rotation)
    overlay->SetL(1.0f, 1.0f, overlayPosition, 0.0f);

    // we can check what this looks like by rendering to the preview
    preview->RenderL();

    // We can then double the size of the overlaid, rotate it 45 degrees clockwise 
    // and move it down ten screen pixels.
    TReal32 overlayScaleX = 0.0f;
    TReal32 overlayScaleY = 0.0f;
    overlay->GetScaleL(overlayScaleX, overlayScaleY);

    overlayScaleX *= 2.0f;
    overlayScaleY *= 2.0f;

    TReal32 overlayAngle = overlay->AngleL();

    // Rotate the overlay 45 degrees 
    overlayAngle += 45.0f;
    if (overlayAngle >= 360.0f)
        {
        overlayAngle = overlayAngle - 360.0f;
        }

    // Move down the position of the overlay 10 screen pixels
    overlayPosition = overlay->PositionL();
    overlayPosition.iY += 10;

    // Set overlay with new parameters
    overlay->SetL(overlayScaleX, overlayScaleY, overlayPosition, overlayAngle);

    // Apply overlay parameters and finish with overlay
    overlay->EndL();

    preview->RenderL();

Notes On CAPS Adaptation of Image Processor

The Border Effect accepts PNG images as file and buffer input.

Example

See also

JPEG Image Transform Extension Guide