Avr 06

Avec la VCL, les couleurs (sans transparence) sont codées en Bleu-Vert-Rouge… Pour obtenir du Rouge-Vert-Bleu, une fonction qui inverse le rouge et le bleu (et donc utilisable dans les deux sens de conversion) :

1
2
3
4
5
6
7
8
9
function SwitchRB(RGB: TColor): TColor;
var
  R, G, B: Integer;
begin
  R      :=   RGB div $10000;
  G      := ((RGB mod $10000) div $100) shl  8;
  B      :=  (RGB mod $100  )           shl 16;
  Result := R + G + B;
end;

 
Pour tester si les touches Contrôle ou Majuscule sont enfoncées :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// https://delphi.about.com/cs/adptips2000/a/bltip0400_3.htm
function isCtrlDown : Boolean;
var
  ksCurrent : TKeyboardState;
begin
  GetKeyboardState(ksCurrent);
  Result := ((ksCurrent[VK_CONTROL] and 128) <> 0);
end;

function isShiftDown: Boolean;
var
  ksCurrent : TKeyboardState;
begin
  GetKeyboardState(ksCurrent);
  Result := ((ksCurrent[VK_SHIFT] and 128) <> 0);
end;

 
Pour effectuer une rotation d’une image au format PNG :

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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// https://www.delphipraxis.net/559330-post20.html (sans la fuite mémoire)
procedure SmoothRotate(var aPng: TPngImage; Angle: Extended);

  {Supporting functions: Inutile si on importe System.Math}
  function TrimInt(i, Min, Max: Integer): Integer;
  begin
    if      (i > Max) then Result := Max
    else if (i < Min) then Result := Min
    else                   Result := i;
  end;
  function IntToByte(i: Integer): Byte;
  begin
    if      (i > 255) then Result := 255
    else if (i < 0  ) then Result := 0
    else                   Result := i;
  end;
  function Min(A, B: Double): Double;
  begin
    if (A < B) then Result := A
    else            Result := B;
  end;
  function Max(A, B: Double): Double;
  begin
    if (A > B) then Result := A
    else            Result := B;
  end;
  function Ceil(A: Double): Integer;
  begin
    Result := Integer(Trunc(A));
    if (Frac(A) > 0) then
      Inc(Result);
  end;

  {Calculates the png new size}
  function newsize: TSize;
  var
    fRadians          : Extended;
    fCosine, fSine    : Double;
    fPoint1x, fPoint1y: Double;
    fPoint2x, fPoint2y: Double;
    fPoint3x, fPoint3y: Double;
    fMinx, fMiny      : Double;
    fMaxx, fMaxy      : Double;
  begin
    {Convert degrees to radians}
    fRadians := (2 * Pi * Angle) / 360;

    fCosine := Abs(Cos(fRadians));
    fSine   := Abs(Sin(fRadians));

    fPoint1x := (-aPng.Height * fSine);
    fPoint1y := ( aPng.Height * fCosine);
    fPoint2x := ( aPng.Width  * fCosine - aPng.Height * fSine);
    fPoint2y := ( aPng.Height * fCosine + aPng.Width  * fSine);
    fPoint3x := ( aPng.Width  * fCosine);
    fPoint3y := ( aPng.Width  * fSine);

    fMinx := Min(0, Min(fPoint1x, Min(fPoint2x, fPoint3x)));
    fMiny := Min(0, Min(fPoint1y ,Min(fPoint2y, fPoint3y)));
    fMaxx := Max(fPoint1x, Max(fPoint2x, fPoint3x));
    fMaxy := Max(fPoint1y, Max(fPoint2y, fPoint3y));

    Result.cx := Ceil(fMaxx - fMinx);
    Result.cy := Ceil(fMaxy - fMiny);
  end;
type
  TFColor = record
    b, g, r:Byte
  end;
var
  Top, Bottom, Left, Right: Extended;
  eww, nsw                : Extended;
  fx, fy                  : Extended;
  wx, wy                  : Extended;
  cAngle, sAngle          : Double;
  xDiff, yDiff            : Integer;
  ifx, ify                : Integer;
  px, py                  : Integer;
  ix, iy                  : Integer;
  x, y                    : Integer;
  cx, cy                  : Integer;
  nw, ne, sw, se          : TFColor;
  anw, ane, asw, ase      : Byte;
  P1, P2, P3              : pByteArray;
  A1, A2, A3              : pByteArray;
  dst                     : TPngImage;
  IsAlpha                 : Boolean;
  new_colortype           : Integer;
begin
  anw := 0;
  asw := 0;
  {Only allows RGB and RGBALPHA images}
  if not (apng.Header.ColorType in [COLOR_RGBALPHA, COLOR_RGB]) then
    raise Exception.Create(CAPTION_ROTATION_ERROR);

  IsAlpha := apng.Header.ColorType in [COLOR_RGBALPHA];

  if IsAlpha then new_colortype := COLOR_RGBALPHA
  else            new_colortype := COLOR_RGB;

  with newsize do
  begin
    {Creates a copy}
    dst := TPngImage.CreateBlank(new_colortype, 8, cx, cy);
  end;
  try
    cx := dst.width  div 2;
    cy := dst.height div 2;

    {Gather some variables}
    Angle  :=  Angle;
    Angle  := -Angle * Pi / 180;
    sAngle := Sin(Angle);
    cAngle := Cos(Angle);
    xDiff  := (Dst.Width  - aPng.Width ) div 2;
    yDiff  := (Dst.Height - aPng.Height) div 2;

    {Iterates over each line}
    for y := 0 to Pred(Dst.Height) do
    begin
      P3 := Dst.scanline[y];

      if IsAlpha then
        A3 := Dst.AlphaScanline[y];

      py := 2 * (y - cy) + 1;

      {Iterates over each column}
      for x := 0 to Pred(Dst.Width) do
      begin
        px  := 2 * (x - cx) + 1;
        fx  := (((px * cAngle - py * sAngle) - 1) / 2 + cx) - xDiff;
        fy  := (((px * sAngle + py * cAngle) - 1) / 2 + cy) - yDiff;
        ifx := Round(fx);
        ify := Round(fy);

        {Only continues if it does not exceed image boundaries}
        if ((-1 < ifx) and (ifx < aPng.Width) and (-1 < ify) and (ify < aPng.Height)) then
        begin
          {Obtains data to paint the new pixel}
          eww := fx - ifx;
          nsw := fy - ify;
          iy  := TrimInt(ify + 1, 0, aPng.Height - 1);
          ix  := TrimInt(ifx + 1, 0, aPng.Width  - 1);
          P1  := aPng.Scanline[ify];
          P2  := aPng.Scanline[iy];
          if IsAlpha then A1  := aPng.AlphaScanline[ify];
          if IsAlpha then A2  := aPng.AlphaScanline[iy];
          nw.r := P1[ifx * 3];
          nw.g := P1[ifx * 3 + 1];
          nw.b := P1[ifx * 3 + 2];
          if IsAlpha then anw := A1[ifx];
          ne.r := P1[ix * 3];
          ne.g := P1[ix * 3 + 1];
          ne.b := P1[ix * 3 + 2];
          if IsAlpha then ane := A1[ix];
          sw.r := P2[ifx * 3];
          sw.g := P2[ifx * 3 + 1];
          sw.b := P2[ifx * 3 + 2];
          if IsAlpha then asw := A2[ifx];
          se.r := P2[ix * 3];
          se.g := P2[ix * 3 + 1];
          se.b := P2[ix * 3 + 2];
          if IsAlpha then ase := A2[ix];

          {Defines the new pixel}
          Top           := nw.b +eww * (ne.b - nw.b);
          Bottom        := sw.b +eww * (se.b - sw.b);
          P3[x * 3 + 2] := IntToByte(Round(Top + nsw * (Bottom - Top)));
          Top           := nw.g + eww * (ne.g - nw.g);
          Bottom        := sw.g + eww * (se.g - sw.g);
          P3[x * 3 + 1] := IntToByte(Round(Top + nsw * (Bottom - Top)));
          Top           := nw.r + eww * (ne.r - nw.r);
          Bottom        := sw.r + eww * (se.r - sw.r);
          P3[x * 3]     := IntToByte(Round(Top + nsw * (Bottom - Top)));

          {Only for alpha}
          if IsAlpha then
          begin
            Top    := anw + eww * (ane - anw);
            Bottom := asw + eww * (ase - asw);
            A3[x]  := IntToByte(Round(Top + nsw * (Bottom - Top)));
          end;
        end;
      end;
    end;

    aPng.Assign(dst);
  finally
    dst.Free;
  end;
end;

 
Pour jouer un fichier WAV qui est inclus dans les ressources :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
procedure TfrmCapture.PlaySound(sSound: string);
var
  hFind, hRes: THandle;
  Song       : PChar;
begin
  if (sSound<> '') then
  begin
    hFind := FindResource(HInstance, PWideChar(sSound), 'WAVE');
    if (hFind <> 0) then
    begin
      hRes := LoadResource(HInstance, hFind);
      if (hRes <> 0) then
      begin
        Song := LockResource(hRes);
        if Assigned(Song) then
        begin
          SndPlaySound(Song, snd_ASync or snd_Memory);
        end;
        UnlockResource(hRes);
      end;
      FreeResource(hFind);
    end;
  end;
end;

La liste est très loin d’être exhaustive… mais c’est déjà un bon début :)

Si vous voyez des erreurs à corriger, des optimisations qui pourraient être faites, n’hésitez pas à laisser un commentaire ;)

Share

Pages : 1 2

Lien permanent vers Fonctions Delphi Rédigé par Whiler \\ Tags : , , , ,

3 réponses pour “Fonctions Delphi”

  1. Whiler a dit :

    Ajout de la fonction Beep dans l’unité uWxPlatform.

    Répondre

  2. Whiler a dit :

    Ajout de la fonction BrowseForFolder dans l’unité uWxPlatform.

    Répondre

  3. Whiler a dit :

    Ajout des fonctions IsCtrlDown & IsShiftDown dans l’unité uWxPlatform.

    Répondre

Laisser une réponse

(requis)

(requis)

*

;) (lol) (y) |-( (hi) 8-) (angel) :s (clap) (bow) (tmi) (:| plus »

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.