Combining multiple image effect filters in your C++ FireMonkey applications
In previous blogs and videos, I showed you how to use the FireMonkey image effect components and image effect filters in your C++Builder XE3 Windows and Mac applications. "January 14 - Using Pixel Shader Image Effects in your C++Builder XE3 Windows and Mac apps" showed you how to use an image effect component in the UI of your application. "January 19 - Using Image Effect Filters in your C++Builder XE3 Windows and Mac apps" showed you how to use a single effect filter and save the output bitmap to a file. To use two or more image effect filters together to produce the desired bitmap output you can set an image filter's InputFilter property. According to the Embarcadero DocWiki entry: "Use InputFilter with a stack of filters when you want to put the result of one filter in the input of another filter. For example, if the result of Filter1 is used in Filter2, use the statement Filter2->InputFilter = Filter1;".
Here is an example C++ FireMonkey HD application source code and header file for a simple example that connects two image effects: Sepia Filter and Magnify Filter.
[caption id="attachment_42508" align="alignnone" width="300" caption="Multiple Image Effect Demo Forms Designer and Structure Window"]
[/caption]
MainForm.h:
MainForm.cpp:
The following are screen captures of the demo application and the resulting saved bitmap:


I have also uploaded the complete project to CodeCentral at http://cc.embarcadero.com/item/29314
Here is an example C++ FireMonkey HD application source code and header file for a simple example that connects two image effects: Sepia Filter and Magnify Filter.
[caption id="attachment_42508" align="alignnone" width="300" caption="Multiple Image Effect Demo Forms Designer and Structure Window"]

MainForm.h:
//---------------------------------------------------------------------------
#ifndef MainFormH
#define MainFormH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <FMX.Controls.hpp>
#include <FMX.Forms.hpp>
#include <FMX.Objects.hpp>
#include <FMX.Types.hpp>
#include <FMX.Dialogs.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TImage *Image1;
TImage *Image2;
TButton *OpenButton;
TOpenDialog *OpenDialog1;
TSaveDialog *SaveDialog1;
TTrackBar *SepiaTrackBar;
TLabel *Label1;
TButton *SaveButton;
TLabel *Label2;
TTrackBar *MagnifyTrackBar;
void __fastcall OpenButtonClick(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
void __fastcall SepiaTrackBarChange(TObject *Sender);
void __fastcall SaveButtonClick(TObject *Sender);
private: // User declarations
public: // User declarations
TFilterSepia * MySepiaFilter;
TFilterMagnify * MyMagnifyFilter;
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
MainForm.cpp:
//---------------------------------------------------------------------------
#include <fmx.h>
#pragma hdrstop
#include "FMX.Filter.hpp"
#include "FMX.Filter.Effects.hpp"
#include "MainForm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OpenButtonClick(TObject *Sender)
{
if (OpenDialog1->Execute()) {
Image1->Bitmap->LoadFromFile(OpenDialog1->FileName);
SaveButton->Enabled = true;
MySepiaFilter->Input = Image1->Bitmap;
MySepiaFilter->Amount = SepiaTrackBar->Value / 100;
MyMagnifyFilter->Center = TPointF(Image1->Bitmap->Width/2,Image1->Bitmap->Height/2);
MyMagnifyFilter->Radius = 0.35;
MyMagnifyFilter->InputFilter = MySepiaFilter; // set the Magnify Filter's input to the Sepia output
MyMagnifyFilter->Magnification = MagnifyTrackBar->Value;
Image2->Bitmap = MyMagnifyFilter->Output;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
MySepiaFilter = new TFilterSepia(this);
MyMagnifyFilter = new TFilterMagnify(this);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SepiaTrackBarChange(TObject *Sender)
{
MySepiaFilter->Amount = SepiaTrackBar->Value / 100;
MyMagnifyFilter->InputFilter = MySepiaFilter;
MyMagnifyFilter->Magnification = MagnifyTrackBar->Value;
Image2->Bitmap = MyMagnifyFilter->Output;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SaveButtonClick(TObject *Sender)
{
if (SaveDialog1->Execute()) {
Image2->Bitmap->SaveToFile(SaveDialog1->FileName);
}
}
//---------------------------------------------------------------------------
The following are screen captures of the demo application and the resulting saved bitmap:


I have also uploaded the complete project to CodeCentral at http://cc.embarcadero.com/item/29314
Tags:
32-bit
64-bit
C++
C++Builder
FireMonkey
GPU
Image Effects
Image Filters
MAC OSX
Pixel Shader
Programming
RAD Studio
Windows


David Intersimone (known to many as David I.) is a passionate and innovative software industry veteran-often referred to as a developer icon-who extols and educates the world on Embarcadero developer tools. He shares his visions as an active member of the industry speaking circuit and is tapped as an expert source by the media. He is a long-standing champion of architects, developers and database professionals and works to ensure that their needs are folded into Embarcadero's strategic product plans. David holds a bachelor's degree in computer science from California Polytechnic State University at San Luis Obispo, California.
Comments
-
Sudat Tuladhar Wednesday, 20 November 2013
Dear Sir,
How can i access the individual pixel of a bitmap image using c++ XE5 builder. I see examples for it in delphi XE5 ("startline") but can't find similar example for c++ XE5.
I am a research student in Image Processing.
I would really like to test XE5's image processing ability before buying it. Thank you.
I am running a trial version for now but would like to buy it once i find it helpful for my image processing research.
Thank you -
Please login first in order for you to submit comments
- Page :
- 1
Thank you so much, that is what I look for. Really appreciated.
Great example.