 |
Development
of plug-ins |
 |
Developing external mudules (plug-ins) for pour PhotoFiltre.
Date of this document: January 2004
(Note
by the translator: This page is about 50% translated. Since I only have
a marginal knowledge of
both French and the Delphi programming language, some technical terms
might be translated wrongly.
Just be cautious. -- Jeroen de Bruijn)
Contents
of this document
I) Introduction
II) The different module types
A) Filter modules
B) Image modules
C) Import modules
D) Export modules
E) Tool modules
III) Library compilation options
IV) Export functions
V) Constants and variables
VI) Header initsialization functions
VII) User language functions
VIII) Interfacing functions
IX) Tips and tricks
X) Appendices
A) Delphi units
B) Authorization for plug-in development
I)
Introduction
The extrenal modules (plug-ins) of photofiltre are very clean, but they
are not directly compatible with
any other application. The plug-ins are stored ina folder called "Plugins"
and have the extention ".pfl"
(PhotoFiltre Library). They are simple DLL's developed in Delphy, but
they must comply with several
rules for the results returned by functions. At the initsialization
of PhotoFiltre, the application searches
for plug-ins and loads all the recognized plug-ins.
Personally, I use the Delphi 6 PE edition to develop, but I don't think
there are any problems if you
use an other version of Delphi (I guess).
II)
The different module types
PhotoFiltre uses several types of modules plusieurs types de modules.
Each type is placed in a dedicated menu.
A) Filter modules
They are only aviable in 16 millions color mode (24 bits) without transparency
and are applied to the selected part of the current image.
Rules :
- They should never change the current selection of the image.
- They should never modify the size of the image
- They should be able to cancel or undo their own changes to the image
(cancel / undo)
- They will be placed in the menu Filter >> Other
Examples : Red eye reduction, Automatic adjustments
B) Image modules
These modules are aviable for every image (independent of the number
of colors and transparency)
and the effects will be applied over the whole current image (as opposite
to only applicable to the
selected part of the current image).
Rules :
- They should be able to cancel or undo their own changes to the image
(cancel / undo)
- They will be placed in the menu Image >> Other
Examples : External frameworks with textures, insertion of copyright
notice
C) Import modules
These modules are intended for import functions and are always aviable
(with or without a current image).
Rules :
- They must create a new image
- They may not modify or delete the current immage (if aviable)
- They don't need to be able to cancel or undo their image creation
(user can choose not save the image)
- They are aviable from the menu File >> Import
Examples : Import functions of misc camera's, JPEG2000, opening other
image formats
D) Export modules
These modules are intended to export the current image.
Rules :
- They may never change current image
- They don't need to be able to cancel or undo their image creation
- They are aviable from the menu File >> Export
Examples : JPEG2000, Binary format.
E) Tool modules
These are all modules who can not be fit into any of the other classifications.
Rules :
- They may never modify any image in progress
- They don't need to be able to cancel or undo their image creation
- They are aviable from the menu Tools > Other.
Examples : Image creators, a selection editor, Lossless JPEG rotations,
diaporama
III)
Library
compilation options
All procedures and functions have the instruction 'stdcall' (standard
API).
Integers are 32 bits. The type LongBool is a 32 bits boolean. Character
strings are passed by a PChar
pointer and buffer. The changes in bitmaps are made with 24 bit RGB
(Native PhotoFiltre format).
IV)
Export functions
function RegisterPluginHeader: PPluginHeader;

Returns a pointer with the address of the header structure (see below)
function RegisterPluginLanguage: PPluginLanguage;

Returns a pointer with the address of the language construction.
Allows the module to know the language used by PhotoFiltre This is an
optional function.
function RegisterPluginStruct: PPluginStruct;

Returns a pointer with the address of the main construct (See below)
function RegisterCompatibility: Integer;

Allows to manage the compatibility of the modules. At this moment, the
function will return '1'.
function RegisterApplication: PApplication;

Will return the address of the module applications. It is optional if
the module does not need to save
arameters. If a module does save its parameters, this function is oliged,
because it is used internally.
function Execute: Integer;

The main procedure that executes the module. Returns 0 in event of a
failure or cancellation and returns 1
if the execution was successfull
procedure SetColorPicker(Color: TColor);

For the moduels that use DM_COLOR_PICKER (see ShowForm). This is executed
by PhotoFiltre on each
click on an image to get the color underneat the cursor.
V)
Constants and variables
const
MaxLongStr = 256;
MaxShortStr = 64;
RGBColorCount = 256 * 256 * 256; // 16 millions
of colors
var
PluginErrorMsg: string = 'Error during the execution
of the plug-in !';
type
PApplication = ^TApplication;
PPluginHeader = ^TPluginHeader;
TPluginHeader = packed record
end;
PPluginLanguage = ^TPluginLanguage;
TPluginLanguage = packed record
end;
PPluginStruct = ^TPluginStruct;
TPluginStruct = packed record
end;
EPluginException = class(Exception);
It is not usefull to describe these types in detail as the are only
used internally in the Plugins.pas unit.
VI)
Header initsialization functions
These functions are used to describe the module, its type, its author
and other additional information.
You need to use these functions within the RegisterPluginHeader
function.
procedure SetHeaderAuthor(Author: string);

Name and compyright text of the author. Nom et copyright de l'auteur.
The length is truncated by
MaxShortStr.
procedure SetHeaderCaption(Caption: string);

Name of the module. It is also the name appearing in the menu of PhotoFiltre.
The length of the sting is truncated after 30 characters
The name can end with '...' to indicate the user will get a screen with
adjustable settings.
procedure SetHeaderComment(Comment: string);

Commments with a maximum of 3 lines (#13 to go to the next line).
The length of the string is truncated at MaxLongStr.
procedure SetHeaderMenuOptions(Options: TMenuOptions);

type
TMenuOption = (moRGBColors, moIndexdColors,
moTransparent, moNoTransparent,
moSelected, moNotSelected,
moNeedImage, moNeedMoreThanOneImage);
TMenuOptions = set of TMenuOption;
Allows to deactivate the PhotoFiltre menu if certain
conditions are not met:
moRGBColors:
the current image must be in 16 million colors
moIndexedColors: the current image must be in indexed colors mode
moTransparent: the current image must be transparent
moNoTransparent: the current image should not be transparent
moSelected: the current image must have a selection
moNotSelected: the current image should not have selection
moNeedImage: there has to be one image open atleast
moNeedMoreThanOneImage: at least two images must be open
moImageJpeg: the current image must be a JPEG image (jpg, JPEG, jpe,
jfif)
moImageGif: the current image must be a GIF image
moImagePng: the current image must be a png image
moImageBmp: the current image must be a BMP image (bmp or rle)
moImageTiff: the current image must be a tiff (tif or tiff)
moImagePfs: the current image must be a PFS
procedure SetHeaderPluginType(PluginType: TPluginType);

type TPluginType = (ptFilter, ptImage, ptFileImport, ptFileExport, ptTool);
Sets the module type.
procedure SetHeaderVersion(Version: string);

Version and date of the module.
The string is truncated at MaxShortStr.
VII)
User language functions.
These functions allow you to retrieve information about the language
that is currently used in PhotoFiltre.
They
might be used in RegisterPluginHeader and Execute in order
to set the language for the module.
they are only aviable if the function RegisterPluginLanguage
already has been called.
function GetLanguageCode: string;

Retrieves the language code (two characters) of the language used by
Photofiltre
Examples : "FR", "EN", "DE", "NL"
function GetLanguageStr: string;

Retrieves the name of the language used by PhotoFiltre.
Examples : "Français", "English".
VIII)
Les fonctions d'exécution
These functions allow PhotoFiltre to exchange data with the module.
These functions should be used in the exported Execute function.
procedure BeginFilter(Msg: string = ''; ChangeCursor: Boolean = True);

Shows a message at the start of the execution of the filter in the status
bar.
If Msg is a null string, the default message is used.
ChangeCursor indicates if the cursor should be set to the sandglass
shape during execution.
function DrawSelBorder(Width: Integer; Color: TColor; Antialias:
Boolean): Boolean;

Draw an outline (on the current image) in the shape of the current selection.
No smoothing in indexed
color mode. Aviable for modules of the image or filter type. Returns
TRUE if the evens was succesfull.
procedure EndFilter;

Shows a message at the end of the execution of the filter in the status
bar.
function EnumImages(EnumImageProc: TEnumImageProc): Boolean;

type TEnumImageProc = function (pFileName: PChar; Width, Height, NbColors:
Integer;
TransColor: TColor): LongBool; stdcall;
Cycles trought the opened images list and executes the EnumImageProc
action with the following
parameters:
pFileName : Name of the image (Management of the buffer is handled
by PhotoFiltre)
Width : width of the image
Height : height of the image
NbColors : number of colors used in the image
TransColor : The color number if the image has tranparency or
clNone if there is no transparency.
Must be used before GetBitmapByName and GetThumbByName.
function GetBitmap(Bitmap: TBitmap): Boolean;

Renvoie une copie au format 24 bits de l'image en cours.
Le bitmap doit être en 24 bits et de taille identique à l'image en cours.
(voir GetImgRect, GetImgWidth et GetImgHeight pour
les dimensions de l'image)
La transparence et le nombre de couleurs ne sont pas gérés, il faut
utiliser les fonctions
GetTransparentColor et GetColorCount si nécessaire.
Renvoie vrai en cas de réussite.
function GetBitmapByName(Bitmap: TBitmap; FileName: string): Boolean;

Renvoie une copie au format 24 bits de l'image correspondant au nom
de fichier.
Cette image doit être ouverte dans PhotoFiltre.
Le bitmap doit être en 24 bits et de taille identique à l'image (voir
la fonction EnumImages).
Renvoie vrai en cas de réussite.
function GetColorCount: Integer;

Renvoie le nombre de couleurs de l'image en cours. Renvoie -1 si aucune
image.
function GetExePath: string;

Renvoie le chemin de localisation du programme PhotoFiltre.
function GetImgFileName: string;

Renvoie le nom complet de l'image (avec chemin si l'image provient d'un
fichier).
function GetImgHeight: Integer;

Renvoie la hauteur de l'image en cours. Renvoie 0 si aucune image.
function GetImgInfosByName(FileName: string; var ImageInfos: TImageInfos):
Boolean;

type
TImageInfos = record
FileName:
string;
Width,
Height: Integer;
ColorCount:
Integer;
TransparentColor:
TColor;
end;
Permet de Récupérer les informations sur une image ouverte.
(Voir également EnumImages, GetBitmapByName et GetThumbByName)
function GetImgRect: TRect;

Renvoie les dimensions de l'image en cours sous forme d'un rectangle
(0, 0, Largeur, Hauteur).
Renvoie un rectangle nul si aucune image.
function GetImgWidth: Integer;

Renvoie la largeur de l'image en cours. Renvoie 0 si aucune image.
function GetIniFile: string;

Renvoie le nom complet (avec chemin) du fichier d'initialisation.
Permet d'éviter la création d'un nouveau fichier d'initialisation pour
le module.
function GetOpenPath: string;

Renvoie le chemin en cours pour l'ouverture d'une image.
function GetPluginPath: string;

Renvoie le chemin de localisation des modules (plugins).
function GetSavePath: string;

Renvoie le chemin en cours pour l'enregistrement d'une image.
function GetSelBitmap(Bitmap: TBitmap): Boolean;

Renvoie une copie au format 24 bits de la partie de l'image sélectionnée.
Le bitmap doit être en 24 bits et de taille identique à la sélection.
(voir GetSelRect, GetSelWidth et GetSelHeight pour les dimensions de
la sélection)
La transparence et le nombre de couleurs ne sont pas gérés, il faut
utiliser les fonctions
GetTransparentColor et GetColorCount si nécessaire.
Renvoie vrai en cas de réussite.
function GetSelHeight: Integer;

Renvoie la hauteur de la sélection en cours. Renvoie 0 si aucune sélection.
function GetSelRect: TRect;

Renvoie le rectangle de sélection (limites maximum) de l'image en cours.
Renvoie un rectangle nul si aucune sélection.function
GetSelMask(Bitmap: TBitmap): Boolean;

Renvoie le masque de sélection de l'image en cours au format 24 bits.
Le bitmap doit être en 24 bits et de taille identique à l'image en cours.
(voir GetImgRect, GetImgWidth et GetImgHeight pour
les dimensions de l'image)
La partie sélectionnée est en blanc et le reste en noir.
Renvoie vrai en cas de réussite.
function GetSelWidth: Integer;

Renvoie la largeur de la sélection en cours. Renvoie 0 si aucune sélection.
function GetThumb(Bitmap: TBitmap; BkColor: TColor; BorderSize, ShadowSize:
Integer;
ShadowBkColor: TColor; var R: TRect):
Boolean;

Renvoie une miniature (vignette) de l'image en cours.
Le bitmap doit être au format 24 bits, ses dimensions ne sont pas modifiées.
La taille de la vignette est calculée en fonction de cette taille tout
en conservant les proportions.
BkColor : couleur du fond (zone non affichée)
BorderSize : Taille de la marge (comprise entre 1 et 50 pixels)
ShadowSize : Taille de l'ombrage (comprise entre 1 et 10 pixels)
ShadowBkColor : couleur du fond utilisée par l'ombre pour simuler
l'opacité
R : récupère la région dans la quelle la vignette est affichée
(sans les bords ni l'ombre)
function GetThumbByName(Bitmap: TBitmap; FileName: string; BkColor:
TColor;
BorderSize, ShadowSize: Integer; ShadowBkColor:
TColor; var R: TRect): Boolean;

Renvoie la miniature de l'image correspondant au nom du fichier.
L'image doit être ouverte dans PhotoFiltre (voir GetThumb et
EnumImages)
function GetTransparentColor: TColor;

Renvoie la couleur de transparence de l'image en cours.
Renvoie clNone si la transparence de l'image n'est pas disponible.
function ImageExists: Boolean;

Renvoie vrai si au moins une image est ouverte.
procedure NewImage(Bitmap: TBitmap; FileName: string; Option: TImageOption;
ColorCount: Integer = RVBColorCount; TransColor:
TColor = clNone);

type TImageOption = (ioCreate, ioFile);
Crée une nouvelle fenêtre contenant l'image passée en paramètre. Le
bitmap doit être au format 24 bits.
Si FileName est une chaîne vide, une valeur par défaut sera affectée
(du type 'Sans titre n').
Les valeurs possibles pour Option sont les suivantes :
ioCreate :la source est une image créée ou importée. Les
fonctions d'enregistrement sont activées.
ioFile : la source provient d'un fichier. Les fonctions d'enregistrement
sont désactivées.
ColorCount : nombre de couleurs de l'image (aucune vérification)
TransColor : Active une couleur de transparence si la valeur
est différente de clNone.
function IsSelected: Boolean;

Renvoie vrai si une sélection est en cours dans l'image active.
function PluginManager: Integer;

Renvoie la version du gestionnaire de module interne de PhotoFiltre.
(pour des futurs tests de compatibilité)
procedure SetAlphaBlend(Alpha: TAlphaRange);

type TAlphaRange = 0..100;
Restaure un pourcentage du Bitmap Undo pour créer un effet de semi-transparence.
Disponible en mode 16 millions de couleurs sans transparence pour les
modules de type Filtre.
Renvoie vrai en cas de réussite.
function SetBitmap(Bitmap: TBitmap): Boolean;

Modifie l'image en cours (contenu et taille). Le bitmap doit être au
format 24 bits.
En cas de modification de la couleur de transparence ou du nombre de
couleurs, il faut utiliser les
fonctions SetTransparentColor et SetColorCount pour la mise à
jour.
Renvoie vrai en cas de réussite.
function SetColorCount(ColorCount: Integer): Integer;

Modifie le nombre de couleurs de l'image en cours.
Aucune vérification quand au format de l'image.
Attention, cette procédure modifie toute l'image en cours. Elle doit
être utilisée avec prudence dans
les modules de type Image.
Renvoie le nombre de couleurs de l'image en cas de réussite, 0 en cas
d'échec.
function SetImgFileName(FileName: string): Boolean;

Modifie le nom du fichier de l'image en cours.
A utiliser dans les modules de type Exportation.
function SetSelBitmap(Bitmap: TBitmap; Option: TSelectionOption =
soAuto);

type TSelectionOption = (soAuto, soNone);
Modifie la partie de l'image sélectionnée.
Le bitmap doit être en 24 bits et de taille identique à la sélection.
(voir GetSelRect, GetSelWidth et GetSelHeight pour
les dimensions de la sélection)
Applique le masque de sélection en fonction de la valeur de Option
:
soAuto : lissage automatique
soNone : aucun lissage (pour dessiner un contour par exemple)
function SetTransparentColor(Color: TColor): Boolean;

Permet de modifier la transparence de l'image en cours.
Si Color vaut clNone, la transparence de l'image est annulée, sinon
la couleur de transparence est
modifiée et la transparence est activée.
Cette fonction est disponible en mode couleurs idexées uniquement (<=
256 couleurs).
Attention, cette procédure modifie toute l'image en cours. Elle doit
être utilisée avec prudence dans
les modules de type Image.
Renvoie vrai en cas de réussite.
procedure ShowForm(Form: TForm; Option: TDialogOption;
MainFormCenter:
Boolean = True; CloseWaiting: Boolean = True);

type TDialogOption = (doModal, doPreview, doColorPicker);
Affiche une fiche de paramétrage du module. Il ne faut jamais utiliser
directement les méthodes
Show ou ShowModal pour éviter les conflits avec PhotoFiltre.
Les valeurs possibles pour Option sont les suivantes :
doModal : la fenêtre principale et la palette d'outils sont désactivées
(ceci implique tous les menus et tous les boutons)
doPreview et doColorPicker = les boutons de zoom restent
actifs pour un aperçu
doColorPicker : le mode pipette est activé et la fonction exportée
SetDialogColor est appelée en
cas de clique sur l'image.
doPreview et doColorPicker sont appliquables seulement
si une image est ouverte, sinon la valeur
doModal est utilisée par défaut.
MainFormCenter : centre la fiche dans la fenêtre principale.
CloseWaiting : attend que la fiche se ferme avant de rendre la
main.
procedure ResetSaveMenu;

Désactive le menu et bouton d'enregistrement pour simuler un enregistrement
réussi.
A utiliser dans les modules de type Exportation.
procedure RestoreUndoBitmap;

Restaure l'image en cours en utilisant la dernière version Undo.
A utiliser dans les modules de type Filtre avec aperçu.
function XP_ThemesEnabled: Boolean;

Renvoie vrai si PhotoFiltre utilise les thèmes Windows XP pour l'affichage.
(Sous Windows XP uniquement)
IX)
Conseils
A première vue, le nombre de fonctions peut sembler élevé mais en réalité
chaque type de module
nécessite très peu de fonctions.
Par exemple un module de type Filtre se compose de la façon suivante
:
ShowForm (fiche de paramétrage facultatif)
BeginFilter
GetSelBitmap
SetSelBitmap
EndFilter
Les modules de type Importation sont encore plus simple :
ShowForm (fiche de paramétrage ou Boîte de dialogue)
BeginFilter
NewImage
SetColorCount et SetTransparentColor si nécessaire.
Pour les modules de type Exportation :
ShowForm (fiche de paramétrage ou Boîte de dialogue)
BeginFilter
GetBitmap
GetColorCount et GetTransparentColor si nécessaire.
ResetSaveMenu (facultatif pour indiquer que
l'image est déjà enregistrée)
EndFilter
Seuls les modules de type Image sont plus compliqués car le nombre de
fonctions peut être plus
important en fonction des traitements à effectuer (changement de format,
transparence,
redimensionnement de l'image, ...).
X)
Annexes
A) Unités Delphi pour le développement des modules
L'unité 'PlgInt.pas' est l'interface de base pour faire dialoguer PhotoFiltre
avec les modules. Elle est
conforme aux API Windows mais est assez lourde à manipuler. Pour cette
raison, j'ai implémenté
l'unité 'Plugin.pas' plus orientée Delphi. Elle gère les conversions
de type (PChar, Integer, ...) afin de
simplifier l'utilisation des fonctions. Les deux unités doivent être
présentes dans vos projets.
B) Autorisation de développement
Le développement des modules de type gratuiciel (freeware) est libre
et ne nécessite aucune
autorisation particulière, mais il faut respecter les règles suivantes
:
- pas de publicité quelque soit sa forme (bandeau, image, texte, message
subliminal, ...)
- un lien vers le site officiel de l'auteur est autorisé (utilisez de
préférence la boîte 'A propos')
- le développeur m'informe dans la mesure du possible de ses
projets
Par contre, le développement des modules de type commercial (shareware
et autres) est interdit
sans autorisation explicite de ma part (Antonio DA CRUZ).
|