IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Blog de Gilles Vasseur - Pascal et compagnie

Rotation d'une image - bibliothèque BGRABitmap avec Lazarus (1/2)

Noter ce billet
par , 13/02/2017 à 14h46 (1562 Affichages)
La bibliothèque de graphisme BGRABitmap a fait l’objet de tutoriels de qualité réalisés par son auteur Johann Elsass. Cependant, de nombreuses fonctionnalités de ce produit restent inexploitées et je me propose de les faire découvrir au fur et à mesure de mes propres travaux.

Aujourd’hui, c’est la méthode PutImageAngle de la classe principale TBGRABitmap qui a retenu mon attention. Ainsi que l’indique son nom, cette méthode permet de procéder à une rotation d’une image.

Comme souvent avec BGRABitmap, la méthode se décline selon plusieurs déclarations surchargées :

Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; AOutputBounds: TRect; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false; ACorrectBlur: Boolean = false); overload;
procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false; ACorrectBlur: Boolean = false); overload;
procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; AOutputBounds: TRect; AResampleFilter: TResampleFilter; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false); overload;
procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; AResampleFilter: TResampleFilter; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false); overload;

Dans un premier temps, je vous propose ci-après une petite application qui la met en œuvre dans sa forme la plus simple, à savoir :

Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false; ACorrectBlur: Boolean = false); overload;

Les paramètres essentiels de la méthode sont les suivants :

  • X et Y désignent les coordonnées du point supérieur gauche de l’image qui sera retournée ;
  • Source est l’image de type TBGRABitmap à traiter ;
  • imageCenterX et imageCenterY désignent les coordonnées du centre de symétrie fixé par défaut au coin supérieur gauche de l’image.


Les autres paramètres n’ont pas besoin d’être modifiés souvent si bien qu’une valeur par défaut leur est attribuée :


  • AOpacity indique le degré d’opacité de l’image (de 0 à 255) ;
  • ARestoreOffsetAfterRotation indique si l’image doit être décalée en fonction de l’axe de rotation ;
  • ACorrectBlur filtre l’effet de flou selon des transitions rapides (False) ou lentes (True) entre pixels.


Afin de se rendre compte en action ce que signifient exactement ces paramètres, voici l’interface de l’application d’exemple :


Nom : 2017-02-13_140655.png
Affichages : 350
Taille : 12,8 Ko

Le fichier lfm qui permet de connaître les composants utilisés et leurs propriétés modifiées est le suivant :

Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
object MainForm: TMainForm
  Left = 376
  Height = 516
  Top = 159
  Width = 563
  Caption = 'Test de PUTIMAGEANGLE - BGRABitmap'
  ClientHeight = 516
  ClientWidth = 563
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  Position = poScreenCenter
  LCLVersion = '1.6.2.0'
  object tckbAngle: TTrackBar
    Left = 16
    Height = 25
    Top = 320
    Width = 320
    Frequency = 30
    Max = 360
    OnChange = tckbAngleChange
    PageSize = 30
    Position = 0
    TabOrder = 0
  end
  object tckbX: TTrackBar
    Left = 16
    Height = 25
    Top = 360
    Width = 320
    Max = 100
    OnChange = tckbAngleChange
    Position = 50
    TabOrder = 1
  end
  object tckbY: TTrackBar
    Left = 16
    Height = 25
    Top = 416
    Width = 320
    Max = 100
    OnChange = tckbAngleChange
    Position = 50
    TabOrder = 2
  end
  object lblAngle: TLabel
    Left = 344
    Height = 15
    Top = 320
    Width = 31
    Caption = 'Angle'
    FocusControl = tckbAngle
    ParentColor = False
  end
  object lblX: TLabel
    Left = 344
    Height = 15
    Top = 360
    Width = 7
    Caption = 'X'
    FocusControl = tckbX
    ParentColor = False
  end
  object lblY: TLabel
    Left = 344
    Height = 15
    Top = 416
    Width = 7
    Caption = 'Y'
    FocusControl = tckbY
    ParentColor = False
  end
  object PaintBox: TPaintBox
    Left = 16
    Height = 280
    Top = 24
    Width = 320
    OnPaint = PaintBoxPaint
  end
  object tckbRotCenter: TTrackBar
    Left = 16
    Height = 25
    Top = 470
    Width = 320
    Max = 100
    OnChange = tckbAngleChange
    Position = 50
    TabOrder = 3
  end
  object lbRotCenter: TLabel
    Left = 344
    Height = 15
    Top = 470
    Width = 19
    Caption = 'Axe'
    ParentColor = False
  end
  object cbOffset: TCheckBox
    Left = 360
    Height = 19
    Top = 32
    Width = 68
    Caption = 'Décalage'
    Checked = True
    OnChange = tckbAngleChange
    State = cbChecked
    TabOrder = 4
  end
  object cbBlur: TCheckBox
    Left = 360
    Height = 19
    Top = 64
    Width = 43
    Caption = 'Flou'
    Checked = True
    State = cbChecked
    TabOrder = 5
  end
  object seOpacity: TSpinEdit
    Left = 432
    Height = 23
    Top = 96
    Width = 98
    MaxValue = 255
    OnChange = tckbAngleChange
    TabOrder = 6
    Value = 255
  end
  object lblOpacity: TLabel
    Left = 360
    Height = 15
    Top = 104
    Width = 47
    Caption = 'Opacité :'
    FocusControl = seOpacity
    ParentColor = False
  end
end

Les composants mis en œuvre sont tous présents par défaut dans Lazarus. Il s’agit essentiellement d’une zone de dessin (TPaintBox) et de différents contrôles pour modifier les propriétés de l’image. On remarquera en particulier les TTrackBar toujours très utiles lorsque des intervalles de valeurs raisonnables sont en jeu.

Le principe de l’application est simple : à chaque fois qu’un contrôle voit sa valeur modifiée, il est fait appel à la méthode OnPaint de la TPaintBox. C'est elle qui est chargée de redessiner la surface du canevas de la TPaintBox. Cette méthode OnPaint contient essentiellement un appel à la méthode PutImageAngle appliquée à un objet de type TBGRABitmap provisoire, créé et libéré en lien avec une section try… finally qui assure une gestion sécurisée des ressources allouées pour l’image.

Voici le listing complet de l’application :

Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{ |========================================================================|
  |                                                                        |
  |                  Projet : découverte de BGRABITMAP                     |
  |                  Description : Programme exemple 01 PUTIMAGEANGLE      |
  |                  Unité : main.pas                                      |
  |                  Site : www.developpez.com                             |
  |                  Copyright : © Gilles VASSEUR 2017                     |
  |                                                                        |
  |                  Date:    13/02/2017 13:16:10                          |
  |                  Version : 1.0.0                                       |
  |                                                                        |
  |========================================================================| }
 
unit main;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
  StdCtrls, ExtCtrls, Spin, BGRABitmap, BGRABitmapTypes;
 
type
 
  { TMainForm }
 
  TMainForm = class(TForm)
    cbOffset: TCheckBox;
    cbBlur: TCheckBox;
    lblOpacity: TLabel;
    lbRotCenter: TLabel;
    lblY: TLabel;
    lblX: TLabel;
    lblAngle: TLabel;
    PaintBox: TPaintBox;
    seOpacity: TSpinEdit;
    tckbX: TTrackBar;
    tckbAngle: TTrackBar;
    tckbY: TTrackBar;
    tckbRotCenter: TTrackBar;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure PaintBoxPaint(Sender: TObject);
    procedure tckbAngleChange(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    bmpWork: TBGRABitmap;
  end;
 
var
  MainForm: TMainForm;
 
implementation
 
{$R *.lfm}
 
{ TMainForm }
 
procedure TMainForm.FormCreate(Sender: TObject);
// *** chargement de l'image à la création ***
begin
  bmpWork := TBGRABitmap.Create('logoFPC.png');
end;
 
procedure TMainForm.FormDestroy(Sender: TObject);
// *** libération des ressources ***
begin
  bmpWork.Free;
end;
 
procedure TMainForm.PaintBoxPaint(Sender: TObject);
// *** la PaintBox est repeinte ***
var
  LBmp: TBGRABitmap;
begin
  LBmp := TBGRABitmap.Create(PaintBox.Width, PaintBox.Height, BGRABlack);
  try
    LBmp.PutImageAngle((PaintBox.Width - bmpWork.Width) * tckbX.Position / 100 - 0.5,
      (PaintBox.Height - bmpWork.Height) * tckbY.Position / 100 - 0.5,
      bmpWork,
      tckbAngle.Position,
      bmpWork.Width * tckbRotCenter.Position / 100 - 0.5,
      bmpWork.Height * tckbRotCenter.Position / 100 - 0.5,
      seOpacity.Value, cbOffset.Checked, cbBlur.Checked);
    LBmp.Draw(PaintBox.Canvas, 0, 0, False);
  finally
    LBmp.Free;
  end;
end;
 
procedure TMainForm.tckbAngleChange(Sender: TObject);
// *** une valeur a été modifiée ***
begin
  PaintBox.Invalidate;
end;
end.

En dehors des angles en degrés, les autres mesures sont exprimées en pourcentage de leur valeur maximale. L’abscisse et l’ordonnée de l’image tiennent compte de ses dimensions afin d’assurer, lorsque la correction du décalage est actif et que l’angle de rotation est nul, le maintien de l’image dans les limites définies par la TPaintBox.

Voici enfin un instantané de l’application en action :

Nom : 2017-02-13_140641.png
Affichages : 366
Taille : 32,2 Ko

À vous de jouer !

Lien pour le code source : rotateimage.7z

Envoyer le billet « Rotation d'une image - bibliothèque BGRABitmap avec Lazarus (1/2) » dans le blog Viadeo Envoyer le billet « Rotation d'une image - bibliothèque BGRABitmap avec Lazarus (1/2) » dans le blog Twitter Envoyer le billet « Rotation d'une image - bibliothèque BGRABitmap avec Lazarus (1/2) » dans le blog Google Envoyer le billet « Rotation d'une image - bibliothèque BGRABitmap avec Lazarus (1/2) » dans le blog Facebook Envoyer le billet « Rotation d'une image - bibliothèque BGRABitmap avec Lazarus (1/2) » dans le blog Digg Envoyer le billet « Rotation d'une image - bibliothèque BGRABitmap avec Lazarus (1/2) » dans le blog Delicious Envoyer le billet « Rotation d'une image - bibliothèque BGRABitmap avec Lazarus (1/2) » dans le blog MySpace Envoyer le billet « Rotation d'une image - bibliothèque BGRABitmap avec Lazarus (1/2) » dans le blog Yahoo

Mis à jour 15/02/2017 à 11h35 par gvasseur58

Catégories
Programmation , Free Pascal , Lazarus , Graphisme

Commentaires