Bonjour,
Ma contribution, la compilation conditionnelle en fonction du compilo (oui, je sais, nous sommes dans le monde Delphi, ici, mais ce genre de code peut être utile à plein de gens, alors bon..)
Testé sous Linux / Laz 1.4, XP / Laz 1.6, Win2000 / D7 perso
J'ai cependant noté à l'exécution, lorsque je compare avec d'autres routines du même type (fin de la page citée dans le 1er post) une différence d'affichage de 1 px dans le sens horizontal et 1 autre px dans le sens vertical.
Code : 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 procedure StretchDown(BmpS, BmpD: TBitmap); var PS, PD: PByte; WidthS, WidthD: integer; PaddingD :integer; NbBytes, IncX, IncY, X, Y: integer; StepX, StepY :integer; begin //Largeur d'une ligne y compris Padding {$IFDEF FPC} widthS := uint(bmpS.RawImage.GetLineStart(1)) - uint(bmpS.RawImage.GetLineStart(0)); widthD := uint(bmpD.RawImage.GetLineStart(1)) - uint(bmpD.RawImage.GetLineStart(0)); {$ELSE} // D7 WidthS := integer(BmpS.Scanline[0]) -integer(BmpS.Scanline[1]); WidthD := integer(BmpD.Scanline[0]) -integer(BmpD.Scanline[1]); {$ENDIF} //Nombre d'octets par pixel NbBytes := WidthS div BmpS.Width; //Calcul du pas StepX := (BmpS.Width shl 16) div BmpD.Width; StepY := (BmpS.Height shl 16) div BmpD.Height; //Calcul des alignements PaddingD := WidthD mod BmpD.Width; //Début du tableau de pixels {$IFDEF FPC} bmpD.BeginUpdate(); PS := bmpS.RawImage.GetLineStart(0); PD := bmpD.RawImage.GetLineStart(0); {$ELSE} // D7 PS := bmpS.Scanline[BmpS.Height -1]; PD := bmpD.Scanline[BmpD.Height -1]; {$ENDIF} for Y := 0 to BmpD.Height -1 do begin IncY := (Y *StepY) shr 16 *WidthS; inc(PS, IncY); for X := 0 to BmpD.Width -1 do begin IncX := (X *StepX) shr 16 *NbBytes; inc(PS, IncX); Move(PS^, PD^, NbBytes); dec(PS, IncX); inc(PD, NbBytes); end; dec(PS, IncY); inc(PD, PaddingD); end; {$IFDEF FPC} bmpD.EndUpdate(); {$ENDIF} end;
Qui a raison, qui a tort ? Pour le moment le mystère reste entier, je note seulement que la routine d'Andnotor est écrite ainsi :
et plus bas une utilisation de shr 16,
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 //Calcul du pas StepX := (BmpS.Width shl 16) div BmpD.Width; StepY := (BmpS.Height shl 16) div BmpD.Height;
quand sur la page citée on peut lire, chapitre "Solve 2", :
et plus bas une utilisation de shr 15.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 xP2 := ((src.Width - 1) shl 15) div dst.Width; yP2 := ((src.Height - 1) shl 15) div dst.Height;
Ce qui m'ennuie c'est que je ne vois pas de différence en passant Andnotor de 16 à 15
Les autres "Solve" (3, 4 et 6) utilisent une autre manière de traiter les arrondis :
plus des trunc en veux-tu en voilà plus bas dans le code.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 xscale := dest.Width / src.Width; yscale := dest.Height / src.Height;
J'aimerais bien savoir de quoi il retourne et uniformiser toutes ces routines de manière à avoir des résultats identiques. Sinon, où va le monde ?
Ceci étant dit, je reviens à ce que j'ai écrit dans le post d'origine, concernant la qualité esthétique des réductions à base de scanline : c'est une catastrophe pour ce qui concerne le texte, le code d'Andnotor ne fait pas exception à la règle, désolé !
On ne voit pas de différences avec « l'œil » alors qu'elle est flagrante avec les zones de texte de mon fichier de test :
Et si vous regardez attentivement l'épaule de Lena, vous noterez sur l'image du bas un effet d'escalier plus prononcé que sur celle du haut, ainsi que la couleur qui change un peu (visible aussi au niveau du chapeau, ainsi que la peau, plus claire en bas, plus bronzée en haut).
Mais l'avantage incontestable de la routine d'Andnotor, c'est sa rapidité ! J'avais une routine notée "FastSmoothResize", la plus rapide de toute, hé bien Andnotor va presque trois fois plus vite !
Ça peut être utile...
Encore un grand bravo à lui
Un dernier mot, promis : à n'utiliser qu'en réduction car en agrandissement, la routine se prend les pieds dans le tapis, sous Linux (pas testé les autres environnements) :
![]()
Partager