Stiler, Styles

Jeg har lagt ut et lite eksemplel på hvordan du kan laste opp en stil ved runtime. Egentlig hadde jeg tenkt å bruke en INI-fil, men vi får se om jeg får tid og lyst til å gjøre det (skuffelsen med Firemonkey grafikk bibliotek som jeg nevnte 🙂 )

Siden med innlegget ligger her:

Eksempler->RAD Code Samples->Stiler, Styles

Firemonkey Gråskala

Som en slags avslutning på klagen på Firemonkey ImageLibrary kan jeg jo vise hvordan vi gjør om et RGB til Gråskala i Firemonkey. Det begynner på vanlig måte i hoveddelen med å kaste om på en adresse:

void __fastcall TForm1::menu_IMAGE_GRAYSCALE_Click(TObject *Sender)
{
	if (TabControl1->TabCount < 1 ) {
		return;
	}
	 TTabItem   *myTabItemPtr;

	 // Get a pointer to active tab

	 myTabItemPtr = TabControl1->ActiveTab;

	 // Type cast to class DocPage and
	 // let DocPage do the job
	 ((DocPage *) myTabItemPtr)->Monochrome();

}

Ikke mye hokus pokus i funksjonen ovenfor, men så fortsetter det i dokumentklassen:

// --------------------------------------------------------------------------
//  				Monochrome
// --------------------------------------------------------------------------

void __fastcall DocPage::Monochrome()
{
	try
	{
		TForm14 *dlgMonochrome =  new TForm14(Application);

		dlgMonochrome->Image1->Bitmap = Image1->Bitmap;
		dlgMonochrome->Caption = _T("Monochrome");

		dlgMonochrome->myMonochrome->Input = dlgMonochrome->Image1->Bitmap;
		//dlgBoxBlur->myBoxBlur->BlurAmount = dlgBoxBlur->TrackBar1->Value / 100;
		dlgMonochrome->Image2->Bitmap = dlgMonochrome->myMonochrome->Output;


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

			// Don't forget the undo-stack

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

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

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

			Image1->Bitmap->Assign(dlgMonochrome->Image2->Bitmap);
			//Image1->Bitmap->Monochrome = true;

		}

		dlgMonochrome->DisposeOf();
	}
	catch(...)
	{
		ShowMessage("Monochrome did not succeed");
	}

}

Koden ovenfor viser min måte å lage en dialogboks på, en TForm klasse og så kjøres det en «dlgMonochrome->ShowModal()».

I de fleste av mine filteroperasjoner bruker jeg en dialogboks med to «TImage»-klasser, en for originalen og en for sluttresultatet. Bildet nedenfor viser det ved designtidspunkt i RAD-Studio

Koden for selve TForm-klassen er vist nedenfor.

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

#ifndef MonochromeH
#define MonochromeH
//---------------------------------------------------------------------------
#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 TForm14 : public TForm
{
__published:	// IDE-managed Components
	TImage *Image1;
	TImage *Image2;
	TButton *Cancel;
	TButton *OK;
	void __fastcall OnCreate(TObject *Sender);
	void __fastcall CancelClick(TObject *Sender);
	void __fastcall OKClick(TObject *Sender);
private:	// User declarations
public:		// User declarations
	int iretState;
	TFilterMonochrome * myMonochrome;
	__fastcall TForm14(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm14 *Form14;
//---------------------------------------------------------------------------
#endif

De enkelte funksjonene i klassen ovenfor er det heller ikke mye å si om, de vises nedenfor:

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

#include <fmx.h>
#pragma hdrstop

#include "Monochrome.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm14 *Form14;
//---------------------------------------------------------------------------
__fastcall TForm14::TForm14(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm14::OnCreate(TObject *Sender)
{
	myMonochrome = new TFilterMonochrome(this);

	 myMonochrome->Input = Image1->Bitmap;
	 //TrackBar1->Value = 25;
	 //myPixelate->BlockCount = TrackBar1->Value;
	 Image2->Bitmap = myMonochrome->Output;

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

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

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

Jeg konstruerer et monokrom filter ved inngangen, og så kan du se jeg kobler outputen fra filteret til inputen i Image2. til sist setter jeg en returstatus ved exit tidspunkt.

Kjøring av programmet ser slik ut:

Firemonkey Image Library 2

Først: Det hele starter i Hovedformen, «TForm1», alle menyfunksjoner gjør det, og så jumper programmet i de fleste tilfelle til en funksjon i «DocPage» klassen. Det eneste som gjøres her er å opprette en adressepeker til neste funksjon:

// --------------------- Display Image Properties ---------------

	void __fastcall TForm1::menu_PROPERTIES_Click(TObject *Sender)         // 19
{
	 TTabItem   *myTabItemPtr;

	 // Get a pointer to active tab
	 myTabItemPtr = TabControl1->ActiveTab;

	 // Type cast to class DocPage and
	 // let DocPage do the job
	 ((DocPage *) myTabItemPtr)->ImageProperties();
}

De meste av info finnes i bitmap’en, «TBitmap», og hvordan du henter opp denne er egentlig forklart i dokumentasjonen fra Embarcadero.

// --------------------------------------------------------------------------
//  				Image Properties
// --------------------------------------------------------------------------
void __fastcall DocPage::ImageProperties()
{
	try
	{
		TForm6 *dlgProperties =  new TForm6(Application);

		dlgProperties->Image1->Bitmap = Image1->Bitmap;
		dlgProperties->Caption = _T("Image Properties");

		// Pixelformat
		TPixelFormat myPixelformat = Image1->Bitmap->PixelFormat;
		UnicodeString strPixelformat(PixelFormatToString(myPixelformat));
		dlgProperties->Edit1->Text = strPixelformat;

		// Bitmap Scale
		float BitmapScale = Image1->Bitmap->BitmapScale;
		UnicodeString strBitmapScale(BitmapScale);
		dlgProperties->Edit2->Text = strBitmapScale;

		// Bytes per line
		int BytesPerLine = Image1->Bitmap->BytesPerLine;
		UnicodeString strBytesPerLine(BytesPerLine);
		dlgProperties->Edit3->Text = strBytesPerLine;

		// Bytes per pixel
		int BytesPerPixel = Image1->Bitmap->BytesPerPixel;
		UnicodeString strBytesPerPixel(BytesPerPixel);
		dlgProperties->Edit4->Text = strBytesPerPixel;

		// Bitmap Height
		int Height = Image1->Bitmap->Height;
		UnicodeString strHeight(Height);
		dlgProperties->Edit5->Text = strHeight;

		// Bitmap Width
		int Width = Image1->Bitmap->Width;
		UnicodeString strWidth(Width);
		dlgProperties->Edit6->Text = strWidth;
		// -----------------------------------------------------------------
		// DisplayCount
		iDisplayCount = Screen->DisplayCount;
		UnicodeString strDisplayCount(iDisplayCount);
		dlgProperties->Edit7->Text = strDisplayCount;

		// Desktop Width i pixels (might be for instance dual screen)
		iDesktopWidthInPixels = Screen->DesktopWidth;
		UnicodeString strDesktopWidth(iDesktopWidthInPixels);
		dlgProperties->Edit8->Text = strDesktopWidth;

		// Desktop Height i pixels
		iDesktopHeightInPixels = Screen->DesktopHeight;
		UnicodeString strDesktopHeight(iDesktopHeightInPixels);
		dlgProperties->Edit9->Text = strDesktopHeight;

		// Screen Width in pixels
		iScreenWidthInPixels = Screen->Width;
		UnicodeString strScreenWidth(iScreenWidthInPixels);
		dlgProperties->Edit10->Text = strScreenWidth;

		// Screen Height in pixels
		iScreenHeightInPixels = Screen->Height;
		UnicodeString strScreenHeight(iScreenHeightInPixels);
		dlgProperties->Edit11->Text = strScreenHeight;

		// Work area
		iWorkAreaWidthInPixels = Screen->WorkAreaWidth;
		UnicodeString strWorkAreaWidth(iWorkAreaWidthInPixels);
		dlgProperties->Edit12->Text = strWorkAreaWidth;

		iWorkAreaHeightInPixels = Screen->WorkAreaHeight;
		UnicodeString strWorkAreaHeight(iWorkAreaHeightInPixels);
		dlgProperties->Edit13->Text = strWorkAreaHeight;

		// Junior school math: a**2 + b**2 = c**2
		iScreenSizeInPixels = sqrt(iScreenWidthInPixels*iScreenWidthInPixels + iScreenHeightInPixels*iScreenHeightInPixels);
		UnicodeString strpixsize(iScreenSizeInPixels);
		dlgProperties->Edit14->Text = strpixsize;

        // Guessing 27" monitor as a starter
		iScreenPPI = iScreenSizeInPixels / 27;
		dlgProperties->Edit15->Text = iScreenPPI;

		//UnicodeString strii(17);

		dlgProperties->ComboBox1->Items->Add( 15);
		dlgProperties->ComboBox1->Items->Add( 17);
		dlgProperties->ComboBox1->Items->Add( 19);
		dlgProperties->ComboBox1->Items->Add( 20);
		dlgProperties->ComboBox1->Items->Add( 22);
		dlgProperties->ComboBox1->Items->Add( 24);
		dlgProperties->ComboBox1->Items->Add( 27);
		dlgProperties->ComboBox1->Items->Add( 28);
		dlgProperties->ComboBox1->Items->Add( 32);
		dlgProperties->ComboBox1->Items->Add( 34);
		dlgProperties->ComboBox1->Items->Add( 35);
		dlgProperties->ComboBox1->Items->Add( 43);
		dlgProperties->ComboBox1->Items->Add( 49);

		dlgProperties->ComboBox1->ItemIndex = 6;

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

			//
		}

		dlgProperties->DisposeOf();
	}
	catch(...)
	{
		ShowMessage("Image properties did not succeed");
	}

}

Det som ligger av kode i selve dialogboksen, er å foreta en beregning hver gang du endrer skjermstørrelse. Da beregnes verdien av pixels/inch.

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

void __fastcall TForm6::OnComboBoxChange(TObject *Sender)
{

	UnicodeString strSelected = ComboBox1->Selected->Text;
	int isize = strSelected.ToInt();
	UnicodeString scrSize = Edit14->Text;
	int iscrSize = scrSize.ToInt();
	int iPixPerInch = round(iscrSize / isize);

	Edit15->Text = iPixPerInch;
}