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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
| unit Unit4;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TForm4 = class(TForm)
PaintBox1: TPaintBox;
OpenDialog1: TOpenDialog;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure PaintBox1DblClick(Sender: TObject);
private
public
CachedImage : TBitmap; // image stockée
BackBuffer : TBitmap; // back buffer d'affichage
procedure DrawBackBuffer; // dessin du back buffer
end;
var
Form4: TForm4;
implementation
{$R *.dfm}
uses
{ utilisation du format JPEG }
JPEG {$DEFINE UJPG}
{ utilisation du format PNG par l'unité PNGImage (incluse dans Delphi >= 2006) }
,PNGImage {$DEFINE UPNG}
{ utilisation du format PNG par l'unité PNGLib (Delphi < 2006) }
// {$IFNDEF UPNG},PNGLib {$DEFINE UPNG}{$ENDIF}
{ utilisation du format GIF par l'unité GIFImg (incluse dans Delphi >= 2006) }
// ,GIFImg {$DEFINE UGIF}
{ utilisation du format GIF par l'unité GIFImage (Delphi < 2006) }
// {$IFNDEF UGIF},GIFImage {$DEFINE UGIF}{$ENDIF}
{ utilisation du format TIF par l'unité TIFImage }
// ,TIFImage {$DEFINE UTIF}
;
{ DrawBackBuffer }
procedure TForm4.DrawBackBuffer;
var W, H, PX, PY, PW, PH : LongInt;
II : string;
R : TRect;
begin
// si le backbuffer et l'image ne sont pas encore créées, on sort.
if not (assigned(BackBuffer) and assigned(CachedImage)) then
exit;
// si l'image est vide, on sort.
if CachedImage.Empty then
exit;
// dimension de l'affichage
W := PaintBox1.Width;
H := PaintBox1.Height;
// on redimensionne le backbuffer
BackBuffer.Width := W;
BackBuffer.Height := H;
// on efface le backbuffer
BackBuffer.Canvas.Pen.Color := Color;
BackBuffer.Canvas.Brush.Color := BackBuffer.Canvas.Pen.Color;
BackBuffer.Canvas.FillRect(BackBuffer.Canvas.ClipRect);
// on redimensionne l'image
PW := CachedImage.Width;
PH := CachedImage.Height;
// en prenant en compte des marge d'au moins 10 pixels à partir du bord
while (PW >= (W-20)) or (PH >= (H-20)) do
begin
// reduction de la taille de 85% à chaque passe
// PW = 1024 -> 870 -> 740 -> 629 -> 535 -> 454 -> 386 ...
PW := trunc(PW * 0.85);
PH := trunc(PH * 0.85);
end;
// calcul de la position pour centrer l'image
PX := (W-PW) shr 1;
PY := (H-PH) shr 1;
// on definit le mode du stretch en HALFTONE pour lisser l'image réduite
SetStretchBltMode(BackBuffer.Canvas.Handle, HALFTONE);
// on déssine l'image dans le backbuffer avec StretchBlt
StretchBlt(BackBuffer.Canvas.Handle, PX, PY, PW, PH,
CachedImage.Canvas.Handle,
0, 0, CachedImage.Width, CachedImage.Height,
SRCCOPY);
// on affiche les infos de l'image à l'ecran
// police d'ecriture
BackBuffer.Canvas.Font.Color := Font.Color;
BackBuffer.Canvas.Font.Name := 'Verdana';
BackBuffer.Canvas.Font.Size := 8;
// infos (nom de fichier + dimensions + ratio)
II := ExtractFileName(OpenDialog1.FileName) +
' : ' +
Format('%d x %d : %.2f',
[CachedImage.Width, CachedImage.Height, CachedImage.Width/CachedImage.Height]);
// on ajoute des marges
R := BackBuffer.Canvas.ClipRect;
R.Right := R.Right - 5;
R.Bottom:= R.Bottom - 5;
// on déssine le texte
DrawText(BackBuffer.Canvas.Handle, PChar(II), -1, R, DT_RIGHT or DT_BOTTOM or DT_SINGLELINE);
// on rafraichis la PaintBox
PaintBox1.Invalidate;
end;
procedure TForm4.FormCreate(Sender: TObject);
begin
// DoubleBuffer, pour eviter l'effet de refresh
DoubleBuffered := true;
// creation du BackBuffer
BackBuffer := TBitmap.Create;
BackBuffer.PixelFormat := pf32bit;
// creation de l'image
CachedImage := TBitmap.Create;
CachedImage.PixelFormat := pf32bit;
// gestion des filtres d'extentions dans l'opendialog
OpenDialog1.Filter := 'Images|*.bmp';
{$IFDEF UJPG} OpenDialog1.Filter := OpenDialog1.Filter + ';*.jpg;*.jpeg'; {$ENDIF}
{$IFDEF UPNG} OpenDialog1.Filter := OpenDialog1.Filter + ';*.png'; {$ENDIF}
{$IFDEF UGIF} OpenDialog1.Filter := OpenDialog1.Filter + ';*.gif'; {$ENDIF}
{$IFDEF UTIF} OpenDialog1.Filter := OpenDialog1.Filter + ';*.tif'; {$ENDIF}
// on appel l'ouverture d'image
PaintBox1DblClick(PaintBox1);
end;
procedure TForm4.FormDestroy(Sender: TObject);
begin
// libération du backbuffer
BackBuffer.Free;
// libération de l'image
CachedImage.Free;
end;
procedure TForm4.FormResize(Sender: TObject);
begin
// quand on redimensione la fenêtre, on redessine le backBuffer
DrawBackBuffer;
end;
procedure TForm4.PaintBox1DblClick(Sender: TObject);
begin
// on demande à l'utilisateur d'ouvrir une image
if OpenDialog1.Execute then
begin
// on passe par un TPicture pour prendre en charge
// tout les formats d'images supportés
with TPicture.Create do
try
// chargement du choix de l'utilisateur
LoadFromFile(OpenDialog1.FileName);
// transfer de l'image dans CachedImage (conversion Bitmap)
CachedImage.Width := Width;
CachedImage.Height:= Height;
CachedImage.Canvas.Draw(0, 0, Graphic);
finally
// libération du TPicture
Free;
end;
// et on dessine le BackBuffer
DrawBackBuffer;
end;
end;
procedure TForm4.PaintBox1Paint(Sender: TObject);
begin
// si le backBuffer n'est pas créé, on sort.
if not assigned(BackBuffer) then
exit;
// si le backBuffer est vide, on sort.
if BackBuffer.Empty then
exit;
// affiche le backBuffer dans la PaintBox
PaintBox1.Canvas.Draw(0, 0, BackBuffer);
end;
end. |
Partager