La bibliothèque BGRABitmap est un ensemble d’outils pour le dessin, l’écriture, le traitement des images, etc. Les possibilités offertes par cette bibliothèque sont très vastes. Pour s’en rendre compte, il suffit d’essayer le logiciel LazPaint qui est basé sur cette bibliothèque et développé par le même auteur.
Les avantages les plus évidents de la bibliothèque BGRABitmap, comparée à la bibliothèque standard de Lazarus, sont la gestion de la transparence et le dessin avec anti-crénelage (en anglais anti-aliasing).
La bibliothèque BGRABitmap n’est pas livrée avec Lazarus. Avant de pouvoir l’utiliser, il faut la télécharger et l’installer. Pour télécharger la dernière version de BGRABitmap, rendons-nous sur cette page.
Une fois la bibliothèque téléchargée, il faut décompresser l’archive ZIP et placer les sources de la bibliothèque à l’endroit de notre choix.
Le chemin du dossier devra être indiqué au compilateur, par exemple en ajoutant ce chemin dans les options de notre projet Lazarus (« Projet », « Options du projet », « Chemins », « Autres fichiers unités »).
L’autre possibilité est d’ouvrir l’un des paquets inclus dans les sources de la bibliothèque. Pour une application Lazarus standard, nous aurons besoin du paquet bgrabitmappack.lpk. Une fois ce paquet ouvert, ajoutons-le au projet (« Utiliser », « Ajouter au projet »).
Une partie des exemples de ce tutoriel utilisent le paquet bgrabitmappack4nogui.lpk, qui convient pour les programmes simples (sans interface graphique).
Une fois que nous avons indiqué au compilateur le chemin des sources de la bibliothèque, ajoutons l’unité BGRABitmap dans la liste des unités utilisées par le programme, puis faisons un premier essai de compilation.
Maintenant que nous avons installé la bibliothèque BGRABitmap et que nous avons fait un premier essai de compilation couronné de succès, nous pouvons commencer à explorer les possiblités offertes par cette bibliothèque.
Nous allons donc faire connaissance avec la classe
TBGRABitmap
. La classe TBGRABitmap permet de créer des
images, de dessiner. Nous allons commencer par utiliser la classe
TBGRABitmap dans de simples programmes qui créeront des images en
mémoire et les enregistreront dans des fichiers.
Le plus simple programme utilisant la classe TBGRABitmap est un programme qui crée une image, avec ses dimensions et sa couleur par défaut, la sauvegarde dans un fichier, et libère la mémoire allouée à l’image.
En plus de l’unité BGRABitmap, le programme utilise l’unité
BGRABitmapTypes, qui contient des définitions nécessaires la
plupart du temps. Dans l’exemple ci-dessous, l’unité BGRABitmapTypes
fournit la définition de la constante BGRAWhite
(couleur
blanche).
program ex_001;
uses
SysUtils, BGRABitmap, BGRABitmapTypes;
const
100;
LARGEUR = 100;
HAUTEUR =
var
image: TBGRABitmap;
begin
{ Création d'un carré blanc de cent fois cent pixels. }
image := TBGRABitmap.Create(LARGEUR, HAUTEUR, BGRABitmapTypes.BGRAWhite);
{ Sauvegarde de l'image dans un fichier. }
0), '.png'));
image.SaveToFile(ChangeFileExt(ParamStr(
{ Libération de la mémoire allouée à l'image. }
image.Free;end.
Si nous ne spécifions pas de couleur lors de l’appel du constructeur, la couleur par défaut de l’image sera la couleur transparente.
{ Création d'un carré transparent de cent fois cent pixels. }
image := TBGRABitmap.Create(LARGEUR, HAUTEUR);
Nous pouvons choisir explicitement une image transparente en passant
au constructeur la valeur BGRAPixelTransparent
.
{ Création d'un carré transparent de cent fois cent pixels. }
image := TBGRABitmap.Create(LARGEUR, HAUTEUR, BGRAPixelTransparent);
Quant au fichier dans lequel l’image est sauvegardée, ce peut être un
fichier de type BMP, JPG ou PNG. Cela dépend tout simplement du nom de
fichier que nous passons à la méthode SaveToFile
.
{ Sauvegarde de l'image dans un fichier. }
0), '.bmp'));
image.SaveToFile(ChangeFileExt(ParamStr(0), '.jpg'));
image.SaveToFile(ChangeFileExt(ParamStr(0), '.png')); image.SaveToFile(ChangeFileExt(ParamStr(
Cependant le type PNG est généralement préféré, parce qu’il permet d’exploiter pleinement l’un des atouts de la bibliothèque BGRABitmap, à savoir la transparence. En effet BGRA est l’acronyme de blue, green, red, alpha, où alpha est un octet représentant le degré d’opacité du pixel. La valeur 0 donnera un pixel transparent.
Nous avons donc appris à créer une image, à la sauvegarder dans un fichier et à libérer la mémoire allouée à l’image. Nous pouvons maintenant commencer à dessiner.
Cependant la bibliothèque BGRABitmap met à notre disposition une telle variété d’outils que nous ne savons pas trop lequel choisir pour commencer.
Nous allons commencer par le plus facile et même, comme vous allez le
voir, par le plus familier. Nous allons commencer par utiliser les
méthodes de l’objet TCanvas
.
Car l’auteur de la bibliothèque BGRABitmap a eu la lumineuse idée
d’équiper la classe TBGRABitmap d’un objet Canvas
identique
extérieurement à l’objet homonyme de la classe TForm
de la
bibliothèque standard de Lazarus (ou de Delphi).
Par conséquent, pour peu que nous soyons familier de l’objet
Canvas
de la LCL (la bibliothèque de composants visuels de
Lazarus), nous savons d’ores et déjà dessiner avec la classe TBGRABitmap
!
Voici par exemple un programme qui trace une ligne à travers le carré blanc que nous avons fabriqué tout à l’heure :
program ex_005;
uses
SysUtils, BGRABitmap, BGRABitmapTypes, BGRAGraphics;
procedure Operations(image: TBGRABitmap);
begin
image.Canvas.Pen.Color := BGRAGraphics.clBlue;0, 0);
image.Canvas.MoveTo(
image.Canvas.LineTo(image.Width, image.Height);end;
const
100;
LARGEUR = 100;
HAUTEUR =
var
image: TBGRABitmap;
begin
image := TBGRABitmap.Create(LARGEUR, HAUTEUR, BGRAWhite);
Operations(image);0), '.png'));
image.SaveToFile(ChangeFileExt(ParamStr(
image.Free;end.
Et voici le résultat :
L’objet Pen
, les méthode MoveTo
et
LineTo
s’utilisent exactement comme leurs homonymes de la
LCL. Quant à l’image obtenue, elle est exactement semblable à celle
qu’on aurait obtenue en dessinant dans l’objet Canvas d’une fenêtre
standard.
C’est à la fois le point fort et le point faible de l’objet Canvas : d’être parfaitement compatible avec l’objet Canvas standard, et donc d’offrir des procédures de dessin basiques, c’est-à-dire notamment sans transparence ni anti-crénelage.
Heureusement, l’auteur de la bibliothèque BGRABitmap a eu une autre
lumineuse idée : celle d’équiper la classe TBGRABitmap d’un objet Canvas
de type TCanvasBGRA
, qui lui aussi reprend la syntaxe de
l’objet Canvas standard, mais fournit un résultat plus sophistiqué, en
faisant appel de façon invisible aux fonctions avancées de la
bibliothèque BGRABitmap.
Voici un second exemple de dessin dans l’objet Canvas de type TCanvas :
procedure Operations(image: TBGRABitmap);
begin
with image.Canvas do
begin
Pen.Color := BGRAGraphics.clBlue;
Brush.Color := clSilver;10, 10, 90, 90);
Ellipse(end;
end;
Le résultat est une ellipse crénelée :
Remplaçons Canvas
par CanvasBGRA
.
procedure Operations(image: TBGRABitmap);
begin
with image.CanvasBGRA do
Le reste du code ne change pas. En revanche, le résultat obtenu n’est plus le même :
Un lissage (ou anti-aliasing) a été appliqué à l’ellipse.
Nous avons appris à utiliser la bibliothèque BGRABitmap avec la syntaxe héritée de l’objet Canvas standard.
Nous allons maintenant faire connaissance avec le style de programmation propre à la classe TBGRABitmap. Les fonctions que nous allons découvrir ont une syntaxe un peu plus complexe que les précédentes, parce qu’elles offrent des possibilités supérieures.
Voici, pour commencer, comment tracer une ligne :
procedure Operations(image: TBGRABitmap);
const
10;
EPAISSEUR = var
couleur: TBGRAPixel;begin
0, 0, 255, 255);
couleur := BGRA(10, 10, 90, 90, couleur, EPAISSEUR);
image.DrawLineAntialias(end;
const
100;
LARGEUR = 100;
HAUTEUR =
var
image: TBGRABitmap;
begin
image := TBGRABitmap.Create(LARGEUR, HAUTEUR, BGRAWhite);
Operations(image);0), '.png'));
image.SaveToFile(ChangeFileExt(ParamStr(
image.Free;end.
Et voici le résultat :
Comme vous pouvez le constater, la méthode
DrawLineAntiAlias
permet de choisir l’épaisseur de la ligne
et aussi son degré d’opacité. En outre, comme le nom de la méthode
l’indique, et comme on le voit dans l’image ci-dessus, la ligne est
lisse et non pas crénelée comme les lignes de l’objet Canvas
standard.
Après la ligne, le rectangle :
procedure Operations(image: TBGRABitmap);
const
10;
EPAISSEUR = var
couleur: TBGRAPixel;begin
0, 0, 255); { Par défaut, le quatrième paramètre vaut 255. }
couleur := BGRA(10, 10, 90, 90, couleur, EPAISSEUR);
image.RectangleAntialias(end;
Pour un rectangle plein, nous utiliserons la méthode
FillRectAntiAlias
:
procedure Operations(image: TBGRABitmap);
var
couleur: TBGRAPixel;begin
0, 0, 255);
couleur := BGRA(10, 10, 90, 90, couleur);
image.FillRectAntialias(end;
Pour un rectangle arrondi, nous utiliserons la méthode
RoundRectAntiAlias
:
procedure Operations(image: TBGRABitmap);
const
10;
EPAISSEUR = begin
image.RoundRectAntialias(10, { Abscisse du sommet supérieur gauche. }
10, { Ordonnée du sommet supérieur gauche. }
90, { Abscisse du sommet inférieur droit. }
90, { Ordonnée du sommet inférieur droit. }
20, { Rayon horizontal de l'arrondi. }
20, { Rayon vertical de l'arrondi. }
0, 0, 255),
BGRA(
EPAISSEUR,
[]
);end;
Par défaut, les quatre coins du rectangle sont arrondis. Le dernier paramètre de la méthode permet de modifier ce comportement. Voici un exemple d’un rectangle plein, dont seuls les coins supérieur gauche et inférieur droit sont arrondis :
procedure Operations(image: TBGRABitmap);
var
couleur: TBGRAPixel;begin
0, 0, 255);
couleur := BGRA(
image.FillRoundRectAntialias(10,
10,
90,
90,
20,
20,
couleur,
[rrTopRightSquare, rrBottomLeftSquare]
);end;
Pour tracer une ellipse (et donc aussi un cercle), nous utiliserons
la méthode EllipseAntiAlias
:
procedure Operations(image: TBGRABitmap);
const
2;
EPAISSEUR = begin
image.Fill(BGRAWhite);
image.EllipseAntialias(2, { Abscisse du centre. }
image.Width / 2, { Ordonnée du centre. }
image.Height / 2 - 5, { Rayon horizontal. }
image.Width / 2 - 5, { Rayon vertical. }
image.Height / { Couleur. }
CSSBlue,
EPAISSEUR
);end;
Remarquez qu’au lieu de choisir la couleur de fond de l’image lors de l’appel du constructeur Create (comme le faisaient les exemples précédents), le programme ci-dessus utilise la méthode Fill.
La propriété CustomPenStyle
permet de modifier le style
du trait, par exemple pour dessiner en pontillés :
{ Style de la ligne. }
2, 1); image.CustomPenStyle := BGRAPenStyle(
Pour dessiner une ellipse pleine (et donc aussi un disque), nous
utiliserons la méthode FillEllipseAntiAlias
:
procedure Operations(image: TBGRABitmap);
var
couleur: TBGRAPixel;begin
0, 0, 255);
couleur := BGRA(
image.FillEllipseAntialias(49.5,
49.5,
49,
49,
couleur
);end;
Enfin, pour une ellipse pleine et coloriée de façon dégradée, nous
utiliserons la méthode FillEllipseLinearColorAntialias
:
procedure Operations(image: TBGRABitmap);
begin
image.FillEllipseLinearColorAntialias(2,
image.Width / 2,
image.Height / 2 - 5,
image.Width / 2 - 5,
image.Height / 0, 0, 255), { Couleur de la périphérie. }
BGRA({ Couleur du centre. }
BGRAPixelTransparent
);end;
Nous voici bien loin de l’objet Canvas standard, n’est-ce pas ? Et encore ces quelques exemples ne donnent-ils qu’un premier aperçu des possibilités offertes par la bibliothèque BGRABitmap.
Nous allons à présent nous familiariser avec les fonctions d’affichage de texte.
Pour cette série d’exemples, nous allons créer, non plus une simple application console, mais une application graphique, qui permettra de voir les images créées dans une fenêtre.
Voici le modèle sur lesquels les exemples suivants seront bâtis :
unit ex_018_u;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
BGRABitmap, BGRABitmapTypes;
type
{ TForm1 }
class(TForm)
TForm1 = procedure FormPaint(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormPaint(Sender: TObject);
var
image: TBGRABitmap;begin
100, 100, BGRAWhite);
image := TBGRABitmap.Create(
{ Dessin de l'image dans la fenêtre }
image.Draw({ TForm1.Canvas }
Canvas, 0, { abscisse du sommet supérieur gauche de l'image }
0, { ordonnée du sommet supérieur gauche }
TRUE { dessin opaque }
);
{ Sauvegarde de l'image dans un fichier }
0), '.png'));
image.SaveToFile(ChangeFileExt(ParamStr(
image.Free;end;
On a rassemblé dans la méthode FormPaint
tout le code
nécessaire à la création, à l’affichage et à la destruction l’image. Les
opérations de dessin sont dans une procédure à part comme
précédemment.
Voici un premier exemple d’affichage de texte :
procedure Operations(image: TBGRABitmap);
begin
with image do
begin
24;
FontHeight := TRUE;
FontAntialias := { fsItalic, fsStrikeOut, fsUnderline }
FontStyle := [fsBold]; 5, 5, 'Hello', CSSBlue);
TextOut(end;
end;
Et le résultat obtenu :
La méthode TextOut
admet un cinquième paramètre
facultatif permettant de choisir l’alignement du texte, par exemple
l’alignement à gauche :
5, 5, 'Hello', CSSBlue, taLeftJustify); TextOut(
Ou au centre :
2, 5, 'Hello', CSSBlue, taCenter); TextOut(Width /
Pour centrer l’image verticalement, il y a plusieurs façons de faire,
par exemple celle-ci, qui exploite la propriété
FontFullHeight
:
procedure Operations(image: TBGRABitmap);
begin
with image do
begin
24;
FontHeight := TRUE;
FontAntialias :=
FontStyle := [fsBold];2, (Height - FontFullHeight) / 2, 'Hello', CSSBlue, taCenter);
TextOut(Width / end;
end;
Si vous désirez en savoir plus dès à présent sur les différentes méthodes permettant de centrer horizontalement et verticalement un texte, consultez le code source des exemples 23 à 26.
Pour choisir une autre police que la police par défaut, nous
utiliserons la propriété FontName
:
procedure Operations(image: TBGRABitmap);
begin
with image do
begin
24;
FontHeight := 'Courier New'; FontName :=
Pour donner une inclinaison au texte, vous utiliserez la méthode
TextOutAngle
:
procedure Operations(image: TBGRABitmap);
begin
with image do
begin
24;
FontHeight := TRUE;
FontAntialias :=
FontStyle := [fsBold];
TextOutAngle(25,
5,
450, { angle en dixièmes de degré }
-'Hello',
CSSBlue,
taLeftJustify
);end;
end;
Ou bien nous changerons la valeur de la propriété
FontOrientation
:
procedure Operations(image: TBGRABitmap);
begin
with image do
begin
24;
FontHeight := TRUE;
FontAntialias :=
FontStyle := [fsBold];
450;
FontOrientation := -
25, 5, 'Hello', CSSBlue, taLeftJustify);
TextOut(end;
end;
La méthode TextRect
permet d’inscrire le texte dans un
rectangle :
image.TextRect(5, 5, 95, 95),
Rect('Texte avec retour automatique à la ligne',
{ taLeftJustify, taRightJustify }
taCenter, { tlTop, tlBottom }
tlCenter,
CSSBlue );
La méthode TextShadow
permet d’obtenir un effet d’ombre
:
procedure Operations(image: TBGRABitmap);
var
texte: TBGRABitmap;begin
texte := TextShadow(100, { Largeur de l'image. }
100, { Hauteur de l'image. }
'Hello', { Texte. }
24, { Taille de la police. }
{ Couleur du texte. }
CSSBlue, { Couleur de l'ombre. }
BGRABlack, 5, { Décalage horizontal. }
5, { Décalage vertical. }
5 { Rayon de l'ombre. }
);
0, 0, texte, dmDrawWithTransparency);
image.PutImage(
texte.Free;end;
Voilà un premier aperçu des méthodes d’affichage de texte. Si vous souhaitez donner de l’épaisseur à vos lettres et obtenir un effet d’éclairage, avec ombre et reflets, consultez l’exemple 32.
Jusqu’ici nous avons dessiné et écrit dans un carré blanc ou transparent. Nous allons maintenant effectuer diverses opérations sur une image préexistante, à savoir la photographie d’un tableau. Il s’agit d’un tableau de Camille Corot intitulé L’Étang de Ville-d’Avray. Ce tableau est conservé au musée des Beaux-Arts de Strasbourg.
Pour créer une image de type TBGRABitmap à partir du fichier corot.jpg, le plus simple est de passer le nom du fichier, comme unique paramètre, au constructeur de la classe TBGRABitmap :
program ex_033;
uses
SysUtils, BGRABitmap, BGRABitmapTypes;
const
'corot.jpg';
FICHIER =
var
image: TBGRABitmap;
begin
{ Création d'une image à partir d'un fichier. }
image := TBGRABitmap.Create(FICHIER);
{ Sauvegarde de l'image dans un fichier. }
0), '.png'));
image.SaveToFile(ChangeFileExt(ParamStr(
{ Libération de la mémoire allouée à l'image. }
image.Free;end.
Le fichier de type PNG produit par le programme est la réplique exacte de l’image originale.
La bibliothèque BGRABitmap s’est occupée pour nous des dimensions de
l’image, et la conversion du type JPG vers le type PNG s’est faite
automatiquement, en fonction du nom de fichier passé à la méthode
SaveToFile
.
Nous aurions pu procéder autrement, à savoir créer une image vierge
aux dimensions de l’image JPG, puis appeler la méthode
LoadFromFile
:
procedure Operations(image: TBGRABitmap);
const
'corot.jpg';
FICHIER = begin
image.LoadFromFile(FICHIER);end;
var
image: TBGRABitmap;
begin
800, 571); image := TBGRABitmap.Create(
Maintenant que nous savons charger une image depuis un fichier, nous
allons effectuer différentes manipulations sur cette image, et pour
commencer, nous allons en découper un morceau. Pour ce faire nous
utiliserons la fonction GetPart
, qui reçoit un paramètre de
type TRect
:
procedure Operations(image: TBGRABitmap);
var
partie: TBGRABitmap;begin
300, 400, 400, 500)) as TBGRABitmap;
partie := image.GetPart(Rect(0), '.png'));
partie.SaveToFile(ChangeFileExt(ParamStr(
partie.Free;end;
Ce qui donne le résultat suivant :
Soit dit en passant, le même résultat peut être obtenu avec un code
plus court, au moyen de la fonction BGRAReplace
:
const
'corot.jpg';
FICHIER =
var
image: TBGRABitmap;
begin
image := TBGRABitmap.Create(FICHIER);
BGRAReplace(
image,300, 400, 400, 500))
image.GetPart(Rect(
);
0), '.png'));
image.SaveToFile(ChangeFileExt(ParamStr(
image.Free;end.
À présent nous allons faire une image en noir et blanc, au moyen de
la méthode FilterGrayScale
:
procedure Operations(image: TBGRABitmap);
var
noir_et_blanc: TBGRABitmap;begin
as TBGRABitmap;
noir_et_blanc := image.FilterGrayScale 0), '.png'));
noir_et_blanc.SaveToFile(ChangeFileExt(ParamStr(
noir_et_blanc.Free;end;
const
'corot.jpg';
FICHIER =
var
image: TBGRABitmap;
begin
image := TBGRABitmap.Create(FICHIER);
Operations(image);
image.Free;end.
À vrai dire, il s’agit plutôt de différents tons de gris, comme l’indique le nom de la méthode.
À présent nous allons redimensionner l’image originale, au moyen de
la méthode Resample
:
procedure Operations(image: TBGRABitmap);
var
reduction: TBGRABitmap;begin
reduction := image.Resample(350,
250,
{ rmSimpleStretch }
rmFineResample as TBGRABitmap;
)
0), '.png'));
reduction.SaveToFile(ChangeFileExt(ParamStr(
reduction.Free;end;
L’option rmFineResample
donne un résultat de meilleure
qualité ; l’option rmSimpleStretch
donne un résultat plus
rapide.
Si vous souhaitez apprendre comment accéder directement aux pixels de l’image, reportez-vous directement au code source de l’exemple 40.
Si vous souhaiter apprendre comment utiliser un masque afin d’obtenir une image inscrite dans une forme autre qu’un rectangle, par exemple un ovale, reportez-vous à l’exemple 41.
Pour terminer, nous allons apprendre à réaliser une animation basée sur les fonctions de la bibliothèque BGRABitmap. On entend par animation une image qui change à intervalles de temps réguliers et qui produit l’illusion d’un mouvement.
Nous allons donc réaliser une application graphique. Cette application permettra à l’utilisateur de déplacer une dame sur une ligne d’échiquier, au moyen des flèches gauche et droite du clavier.
L’image de la dame, en se déplaçant, ne devra pas effacer les rayures des cases noires, sauf bien entendu pour la partie que le corps de la dame couvrira. Les parties couvertes devront être restaurées après le passage de la dame. Cela sera fait de la façon la plus économique, c’est-à-dire en restaurant seulement la partie de l’image concernée, et non pas tout l’échiquier.
Toutes ces opérations se feront dans un écran virtuel, une image de type TBGRABitmap. Une fois ces opérations terminées, le contenu de l’écran virtuel sera copié dans l’objet Canvas de la fenêtre.
Voici le code complet de l’unité :
unit ex_042_u;
{$MODE objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, LMessages, LCLType,
BGRABitmap, BGRABitmapTypes;
type
{ TForm1 }
class(TForm)
TForm1 = procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure FormPaint(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure WMEraseBkgnd(var message: TLMEraseBkgnd); message LM_ERASEBKGND;
private
{ private declarations }
{ Écran virtuel. }
ecran_virtuel, { Image de la dame. }
dame, { Image pour la restauration de l'arrière-plan. }
sauvegarde: TBGRABitmap; integer; { Position de la dame. }
fX, fY: public
{ public declarations }
procedure DessinDame(const aX, aY: integer);
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
const
5;
STEP =
procedure TForm1.FormCreate(Sender: TObject);
var
fond: TBGRABitmap;begin
{ Création de l'écran virtuel. }
320, 40);
ecran_virtuel := TBGRABitmap.Create(
{ Création de l'image de la dame à partir du fichier. }
'dame.bmp');
dame := TBGRABitmap.Create(
{ Remplacement du bleu par de la "couleur transparente". }
dame.ReplaceColor(CSSMidnightBlue, BGRAPixelTransparent);
{ Création de l'image de fond à partir du fichier. }
'ligne.bmp');
fond := TBGRABitmap.Create(
{ Dessin du fond sur l'écran virtuel. }
0, 0, fond, dmSet);
ecran_virtuel.PutImage(
{ Libération de l'image de fond. }
fond.Free;
{ Dessin de la dame à sa position initiale. }
0, 0);
DessinDame(end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
0), '.png'));
ecran_virtuel.SaveToFile(ChangeFileExt(ParamStr(
ecran_virtuel.Free;
dame.Free;
sauvegarde.Free;end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
case Key of
if fX >= 000 + STEP then DessinDame(fX - STEP, fY);
VK_LEFT : if fX <= 280 - STEP then DessinDame(fX + STEP, fY);
VK_RIGHT: end;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
{ Dessin de l'écran virtuel dans la fenêtre }
0, 0);
ecran_virtuel.Draw(Canvas, end;
procedure TForm1.FormShow(Sender: TObject);
begin
BorderStyle := bsSingle;
ClientWidth := ecran_virtuel.Width;
ClientHeight := ecran_virtuel.Height;end;
procedure TForm1.WMEraseBkgnd(var message: TLMEraseBkgnd);
begin
{ Procédure créée et laissée vide à dessein, pour que le fond de la fenêtre ne soit pas effacé }
end;
procedure TForm1.DessinDame(const aX, aY: integer);
begin
{ Restauration du fond sauf au premier appel de la procédure }
if Assigned(sauvegarde) then
ecran_virtuel.PutImage(fX, fY, sauvegarde, dmSet);{ Mise à jour de l'image de sauvegarde en vue de la prochaine restauration }
40, aY + 40)));
BGRAReplace(sauvegarde, ecran_virtuel.GetPart(Rect(aX, aY, aX + { Dessin de la dame à sa nouvelle position }
ecran_virtuel.PutImage(aX, aY, dame, dmDrawWithTransparency);{ Enregistrement de la position }
fX := aX;
fY := aY;{ Rafraîchissement de la fenêtre }
Invalidate;end;
end.
Arrêtons-nous sur quelques endroits intéressants de ce code. L’image
de la dame provient du fichier dame.bmp, dont la couleur de
fond est un certain bleu arbitrairement choisi dont on passe la valeur à
la méthode ReplaceColor
:
{ Création de l'image de la dame à partir du fichier. }
'dame.bmp');
dame := TBGRABitmap.Create(
{ Remplacement du bleu par de la "couleur transparente". }
dame.ReplaceColor(CSSMidnightBlue, BGRAPixelTransparent);
Les opérations sur l’écran virtuel se font dans la procédure
DessinDame
:
procedure TForm1.DessinDame(const aX, aY: integer);
begin
{ Restauration du fond sauf au premier appel de la procédure }
if Assigned(sauvegarde) then
ecran_virtuel.PutImage(fX, fY, sauvegarde, dmSet);{ Mise à jour de l'image de sauvegarde en vue de la prochaine restauration }
40, aY + 40)));
BGRAReplace(sauvegarde, ecran_virtuel.GetPart(Rect(aX, aY, aX + { Dessin de la dame à sa nouvelle position }
ecran_virtuel.PutImage(aX, aY, dame, dmDrawWithTransparency);{ Enregistrement de la position }
fX := aX;
fY := aY;{ Rafraîchissement de la fenêtre }
Invalidate;end;
Le transfert de l’écran virtuel vers la fenêtre se fait dans la
méthode FormPaint
:
procedure TForm1.FormPaint(Sender: TObject);
begin
{ Dessin de l'écran virtuel dans la fenêtre }
0, 0);
ecran_virtuel.Draw(Canvas, end;
La dame glisse vers la gauche ou vers la droite, en fonction des touches sur lesquelles l’utilisateur appuie. Les rayures à l’arrière-plan sont préservées.
Voilà ! Nous avons fait connaissance avec la bibliothèque BGRABitmap.
Vous pouvez trouver d’autres tutoriels en français, dont certains d’un niveau plus avancé, sur cette page.
Si vous le souhaitez, vous pouvez télécharger ce tutoriel avec ses exemples.