This document gives you more information about the image effects and filters.
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();
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(); }
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();
Most mobile imaging applications render full-resolution images twice:
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.
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 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;
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:
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.
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.
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 do not introduce their own areas or coordinate systems. In this regard, Zoom and pan are equivalent to a preview.
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.
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();
The Border Effect accepts PNG images as file and buffer input.