Directional Blur i C++ Builder

Alle disse blur-funksjonene blir gansle like etter hvert, men ok. Du ser jeg har kodet dem og fått det til 🙂 Det meste er jo også greit forklart i dokumentasjonen. Her ser du directional blur ved design tidspunkt:

Directional Blur
Directional Blurr

Igjen ser du min vanlige layout: 2 TImage, en for originalen og en annen for resultatet. Denne gang er det en ekstra trackbar, nemlig for vinkelen. Jeg fikk ikke så stor endring i blur-bildet ved endring av vinkelen, men det har muligens med utvekslingen i trackbar 2 å gjøre. Du kan prøve deg frem.

//---------------------------------------------------------------------------

#ifndef DirectionalBlurH
#define DirectionalBlurH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <FMX.Controls.hpp>
#include <FMX.Forms.hpp>
#include <FMX.Controls.Presentation.hpp>
#include <FMX.StdCtrls.hpp>
#include <FMX.Types.hpp>
#include <FMX.Effects.hpp>
#include <FMX.Filter.Effects.hpp>
#include <FMX.Objects.hpp>
//---------------------------------------------------------------------------
class TForm10 : public TForm
{
__published:	// IDE-managed Components
	TImage *Image1;
	TImage *Image2;
	TTrackBar *TrackBar1;
	TButton *Cancel;
	TButton *OK;
	TLabel *Label1;
	TLabel *Label2;
	TTrackBar *TrackBar2;
	void __fastcall OnCreate(TObject *Sender);
	void __fastcall TrackBar1Change(TObject *Sender);
	void __fastcall TrackBar2Change(TObject *Sender);
	void __fastcall CancelClick(TObject *Sender);
	void __fastcall OKClick(TObject *Sender);
private:	// User declarations
public:		// User declarations
	int iretState;
	//TFilterSharpen * MySharpenFilter;
	//TFilterGaussianBlur *myGaussianBlur;
	//TFilterBoxBlur *myBoxBlur;
	//TFilterRadialBlur *myRadialBlur;
	TFilterDirectionalBlur *myDirectionalBlur;

	__fastcall TForm10(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm10 *Form10;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------

#include <fmx.h>
#pragma hdrstop

#include "DirectionalBlur.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm10 *Form10;
//---------------------------------------------------------------------------
__fastcall TForm10::TForm10(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm10::OnCreate(TObject *Sender)
{
	myDirectionalBlur = new TFilterDirectionalBlur(this);

	myDirectionalBlur->Input = Image1->Bitmap;
	myDirectionalBlur->BlurAmount = TrackBar1->Value / 10;
	Image2->Bitmap =myDirectionalBlur->Output;
    TrackBar2->Value = 0;
	myDirectionalBlur->Angle = TrackBar2->Value;

}
//---------------------------------------------------------------------------
void __fastcall TForm10::TrackBar1Change(TObject *Sender)
{
	myDirectionalBlur->BlurAmount = TrackBar1->Value / 10;
	Image2->Bitmap = myDirectionalBlur->Output;

}
//---------------------------------------------------------------------------
void __fastcall TForm10::TrackBar2Change(TObject *Sender)
{
	myDirectionalBlur->Angle = TrackBar1->Value;
	Image2->Bitmap = myDirectionalBlur->Output;

}
//---------------------------------------------------------------------------
void __fastcall TForm10::CancelClick(TObject *Sender)
{
	iretState = 0;
	Close();

}
//---------------------------------------------------------------------------
void __fastcall TForm10::OKClick(TObject *Sender)
{
	iretState = 1;
	Close();

}
//---------------------------------------------------------------------------

Koden i dokument klassen, Docpage, er også ganske grei. Det er i denne klassen det meste foregår. Jeg lister det hele selv om det blir mye av det samme hver gang. Jeg har en mengde funsjoner jeg tester ut, så du får plukke ut de «#include» setningene du trenger 🙂

//---------------------------------------------------------------------------

#ifndef DocPageH
#define DocPageH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <FMX.Controls.hpp>
#include <FMX.Forms.hpp>
#include <FMX.Menus.hpp>
#include <FMX.Types.hpp>
#include <FMX.Controls.Presentation.hpp>
#include <FMX.StdCtrls.hpp>
#include <FMX.TabControl.hpp>
#include <FMX.Layouts.hpp>
#include <FMX.ListBox.hpp>
#include <FMX.Dialogs.hpp>
#include <FMX.ImgList.hpp>
#include <System.ImageList.hpp>
#include <FMX.Colors.hpp>
#include <FMX.ExtCtrls.hpp>
#include "FMX.Filter.hpp"
#include "FMX.Filter.Effects.hpp"
#include <System.Rtti.hpp>
#include <FMX.Platform.hpp>
#include <FMX.Surfaces.hpp>

//#include <boost/lockfree/stack.hpp>
//#include <boost/atomic.hpp>
#include <stack>
#include <boost/ptr_container/ptr_list.hpp>
#include <boost/array.hpp>
#include "ImageProperties.h"
#include "Sepia.h"
#include "Sharpen.h"
#include "GaussianBlur.h"
#include "BoxBlur.h"
#include "RadialBlur.h"
#include "DirectionalBlur.h"
#include "Emboss.h"
#include "Pixelate.h"
#include "BrightnessContrast.h"
#include "Monochrome.h"
#include "Wave.h"
//#include "menu1.h"
#include "Rotate.h"
#include <string>
//#include "LayerType.h"
#include "LayerItem.h"
#include "PencilStroke.h"
#include "PaperSketch.h"

#include <System.Zip.hpp>

#include "RightFrame.h"

Det burde antagelig være unødvendig å liste hele denne klassen for hvert enkelt eksempel, men da har du alt om du ikke har lest tidligere eksempler 🙂


class TUndoItem : public TObject
{
public:
	TBitmap * UndoBitmap;
	String  * UndoName;

	TUndoItem() : TObject()
	{
		UndoBitmap = 0;
		UndoName = 0;
	}

	~TUndoItem()
	{
		if( UndoBitmap != 0) {
			delete UndoBitmap;
			UndoBitmap = 0;
		}
		if (UndoName != 0) {
			delete UndoName;
			UndoName = 0;
		}

    }
};


// --------------------------------------------------------------------------
//                  class DocPage
// --------------------------------------------------------------------------
class DocPage : public TTabItem
{
private:



public:

	// ----------------------------------------------
	// Page and screen sizes
	enum ePageSizeTypes {
		ePixels,
		eInches,
		eMilliMetres
	};

	ePageSizeTypes 	eSizeType;   		// pixels, inches, etc...

	float		fPageWidth;         	// Page Width
	float		fPageHeight;       		// Page Height
	int  		iPageWidthInPixels; 	// Page Width in Pixels
	int  		iPageHeightInPixels;	// Page Height in Pixels

	int  		iDisplayCount; 			// Display count
	int         iScreenWidthInPixels;   // Screen Width in pixels
	int         iScreenHeightInPixels;  // Screen Height in pixels
	int         iScreenSizeInPixels;    // Screen Size in pixels
	float       fScreenSizeInInches;    // Screen Size In Inches
	float       fScreenSizeInMM;        // Screen Size In MM
	int         iScreenPPI;             // Screen ppi
	int         iDesktopWidthInPixels;  // Desktop Width (Dualscreen?)
	int         iDesktopHeightInPixels; // Desktop Height
	int 		iWorkAreaWidthInPixels; // Work Area in Pixels
	int         iWorkAreaHeightInPixels;//

	// -----------------------------------------------
	// Zip class
	//
	TZipFile   * myZipFile;

	// -----------------------------------------------
	// Testing Frame  (Layer list, etc...)
	//
	TFrame2 *myFrame;

	// -----------------------------------------------
	// Pathnames Win 10:
    //
	// ProgHomeDir 		- c:\Users\svein\AppData\Roaming\Gamlisen\
	// ProjectFileComp  - c:\Users\svein\AppData\Roaming\Gamlisen\anyname.zip
	// ProjectFile      - c:\Users\svein\AppData\Roaming\Gamlisen\anyname.gam
	// ProjectIndexCount- c:\Users\svein\AppData\Roaming\Gamlisen\nnnn
	// ProjectIniFile   - c:\Users\svein\AppData\Roaming\Gamlisen\Gamlis.ini
	// ProjectTempComp  - c:\Users\svein\AppData\Roaming\Gamlisen\Comp2020\
	// ProjectWorkDir   - c:\Users\svein\AppData\Roaming\Gamlisen\G20200501nnnn\
	// ProjectItems     - c:\Users\svein\AppData\Roaming\Gamlisen\G20200501nnnn\Gamlis.ini
	// ProjectItems     - c:\Users\svein\AppData\Roaming\Gamlisen\G20200501nnnn\Image1.png
	// ProjectItems     - c:\Users\svein\AppData\Roaming\Gamlisen\G20200501nnnn\etc...anyfile
	// ProjectBackup    - c:\Users\svein\AppData\Roaming\Gamlisen\Backup\
	//
	System::UnicodeString *ProgHomeDir;
	System::UnicodeString *ProjectFileComp;
	System::UnicodeString *ProjectFile;
	int                    ProjectIndexCount;
	System::UnicodeString *ProjectIniFile;
	System::UnicodeString *ProjectTempComp;
	System::UnicodeString *ProjectWorkDir;
	System::UnicodeString *ProjectBackup;

	// -----------------------------------------------
	// Page Images and Bitmaps

	TFramedScrollBox *FramedScrollBox1; // TFramed ScrollBox
	TLayout 		* Layout1;          // TLayout
	TTabControl     * myTabControl;     // TabControl

	TImage 			* Image1;	        // TImage
	TBitmap			* myBitmap; 	    // TBitmap

	TImage  		* PasteImage;       // Temp Images
	TImage  		* WorkImage;        //

	TSelection 		* mySelection;
	float   	 	zoomFactor;

	// ----------------------------------------------
	// Layers
	TLayerItem *LayerItem;

	boost::ptr_list<TLayerItem> LayerList;
	boost::ptr_list<TLayerItem>::iterator iterLayers;

	TListBox *myLayerListBox;

	// ---------------------------------------------
	// Undo Stack
	TUndoItem  *UndoItem;

	std::stack<TUndoItem *> mystack;

	// ---------------------------------------------

	DocPage(TTabControl *Parent);   // Constructor
	~DocPage();                     // Destructor

void __fastcall ImageProperties();  // Display  image properties

void __fastcall Copy();         // Edit Copy
void __fastcall Paste();        // Edit Paste
void __fastcall UnDo();         // Edit undo
void __fastcall SepiaFilter();  // Sepia Filter
void __fastcall SharpenFilter();// Sharpening Filter
void __fastcall CropFilter(TSelection *localSelection);   // Crop
void __fastcall Rotate();       // Rotate image
void __fastcall Rotate180Click(TObject *Sender); 		// Rotate 180
void __fastcall Rotate90CWClick(TObject* Sender);       // Rotate 90 CW
void __fastcall Rotate90CCWClick(TObject *Sender);      // Rotate 90 CCW
void __fastcall FlipHorizontallyClick(TObject *Sender); // Flip Horizontally
void __fastcall FlipVerticallyClick(TObject *Sender);   // Flip Vertically
void __fastcall GaussianBlur();         // Gaussian Blur
void __fastcall BoxBlur();              // Box Blur
void __fastcall RadialBlur();           // Radial Blur
void __fastcall DirectionalBlur();      // Directional Blur
void __fastcall Emboss();               // Emboss
void __fastcall Pixelate();             // Pixelate
void __fastcall BrightnessContrast();   // Brightness / Contrast
void __fastcall Monochrome();           // MonoChrome
void __fastcall Wave();                 // Wave

void __fastcall ScaleUp();              // Scale Up
void __fastcall ScaleDown();            // Scale Down
void __fastcall Zoom(float Val);        // Zoom

void __fastcall PencilStroke();         // Pencil Stroke
void __fastcall PaperSketch();          // Paper Sketch

void __fastcall FileSaveAs();

//void __fastcall OnMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, bool &Handled);

	void __fastcall LayerButtonShowClick();
	void __fastcall LayerButtonHideClick();
	void __fastcall LayerButtonDownClick();
	void __fastcall LayerButtonUpClick();
	void __fastcall LayerButtonUnlockClick();
	void __fastcall LayerButtonLockClick();
	void __fastcall LayerButtonRemoveClick();
	void __fastcall LayerButtonAddClick();

};
#endif

I implementering av Doc-klassen viser jeg bare DirectionalBlur implementeringen:

// --------------------------------------------------------------------------
//  				Directional Blur
// --------------------------------------------------------------------------

void __fastcall DocPage::DirectionalBlur()
{
	try
	{
		TForm10 *dlgDirectionalBlur =  new TForm10(Application);

		dlgDirectionalBlur->Image1->Bitmap = Image1->Bitmap;
		dlgDirectionalBlur->Caption = _T("DirectionalBlur");

		dlgDirectionalBlur->myDirectionalBlur->Input = dlgDirectionalBlur->Image1->Bitmap;
		dlgDirectionalBlur->myDirectionalBlur->BlurAmount = dlgDirectionalBlur->TrackBar1->Value / 100;
		dlgDirectionalBlur->Image2->Bitmap = dlgDirectionalBlur->myDirectionalBlur->Output;
		dlgDirectionalBlur->myDirectionalBlur->Angle = dlgDirectionalBlur->TrackBar2->Value;

		dlgDirectionalBlur->ShowModal();
		if( dlgDirectionalBlur -> iretState == 1 ) {

			// Don't forget the undo-stack

			UndoItem = new TUndoItem();
			UndoItem->UndoName = new String("DirectionalBlur");
			UndoItem->UndoBitmap = new TBitmap();

			// Have to use "Assign()" because everything are pointers!!!

			UndoItem->UndoBitmap->Assign(Image1->Bitmap);
			mystack.push(UndoItem);

			Image1->Bitmap->Assign(dlgDirectionalBlur->Image2->Bitmap);

		}

		dlgDirectionalBlur->DisposeOf();
	}
	catch(...)
	{
		ShowMessage("Directional Blur did not succeed");
	}


}

Så til slutt et par bilder fra kjøring av programmet:

Directional Blur Runtime
Directional Blur Borland C++
Directional Blur C++ Buildel
Directional Blur C++ Builder

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *

Dette nettstedet bruker Akismet for å redusere spam. Lær om hvordan dine kommentar-data prosesseres.