Skip to content

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.

Multiple Image Effect Demo Forms Designer and Structure Window

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

{ 2 } Comments

  1. Yilmaz Yoru | February 5, 2013 at 1:28 am | Permalink

    Thank you so much, that is what I look for. Really appreciated.
    Great example.

  2. Sudat Tuladhar | November 20, 2013 at 8:55 pm | Permalink

    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

Post a Comment

Your email is never published nor shared. Required fields are marked *

Bad Behavior has blocked 4 access attempts in the last 7 days.

Close