Télécharger le zip
Splendeurs....DH
Au fait, tu ferais comment pour un recto/verso ?
Bonjour,un petit souci sur :SetLength(TSLFinal, BmpFinal.Height);etTSLFinal[y, x].rgbtRed := TabScanLine[v, u].rgbtRed;->> erreur d'étendue..
Salut,Vraiment pas mal du tout... Si tu pouvais juste ajouter de quoi charger et enregistrer une image transformée, ça serait tip-top ! Simon
BLUEPERFECT : pour un recto/verso ? si c'est juste pour inverser/retourner l'image, on peut le faire comme ça :// Mirroir vertical ou horizontal du bitmapprocedure Flip(ABmp:TBitmap; Sens:TSensFlip);begin if Sens=fVertical then ABmp.Canvas.StretchDraw(Rect(0,ABmp.height-1,ABmp.width,-1),ABmp); if Sens=fHorizontal then ABmp.Canvas.StretchDraw(Rect(ABmp.width-1,0,-1,ABmp.Height),ABmp);end;CANTADOR : Je vais vérifier l'erreur. Ça se déclenche dans quelles conditions ?SIMONPELLOQUIN : Je vais rajouter cette option dans la prochaine mise à jour du source.Merci à vous en tout cas !
Salut,le redu est bon mais le code pour y arriver peut et même doit être modifier dans un souci de rapidité mais surtout pour éviter de grosses fuites de mémoire ce qui est malheureusement le cas pour l'instant.Tu as choisi, dans ta fonction, de créer, en guise de paramètre de sortie, un Bitmap que tu ne libères jamais !!! Donc chaque appel à "Distorsion" crée un Bitmap qui reste en mémoire à la fin du programme.pour éviter ces fuites il faut modifier comme suit:{déformation & rendu de l'image}procedure TForm1.Render;var aBMP: TBitmap;begin ... // deformation // aBMP := Distorsion(Quadrangle,Image,clWhite); try RenderBuffer.Canvas.Draw(OX,OY, aBMP); finally aBMP.Free; end; ...end;Rapidement:comme tu ne changes pas les valeurs RGB des pixels il n'est pas utile de les affecter individuellement {transfère les pixels au bon emplacement} TSLFinal[y,x].rgbtRed := TabScanLine[v,u].rgbtRed; TSLFinal[y,x].rgbtGreen := TabScanLine[v,u].rgbtGreen; TSLFinal[y,x].rgbtBlue := TabScanLine[v,u].rgbtBlue;peut être remplacer par: {transfère les pixels au bon emplacement} TSLFinal[y,x] := TabScanLine[v,u];c'est valable aussi pour les deux suivants: if (x<BmpOrigin.Width-2) and (xd>0) then TSLFinal[y,x+1] := TabScanLine[v,u];et if (y<BmpOrigin.Height-2) and (yd>0) then TSLFinal[y+1,x] := TabScanLine[v,u];j'en reste là pour l'instant ;)
Bonjour,A quelle ligne de code et dans quelles conditions apparait l'erreur d'étendue ?Pour un recto/verso ? Retourner l'image ?
ben non ... voici la suite ^^j'ai modifié le code pour éviter des calcules répétitifs et inutiles:function Distorsion(AQuadrangle:TQuadrangle; ABitmap:TBitmap; BkColor:TColor):TBitmap;var TabScanLine, TSLFinal : array of pRVBArray; BmpOrigin : TBitmap; BmpFinal : TBitmap; v, u, x, y, xd, yd : integer; RQWidth, RQHeight : integer; TauxY, TauxX : real; DistAB, DistDC, PosXAB, PosXDC, TmpX : real; DistAD, DistBC, PosYAD, PosYBC, TmpY : real;begin//--calcul de la zone rectangle (rectangle maitre) contenant le quadrangle Ox := min(min(AQuadrangle.A.X,AQuadrangle.B.X),min(AQuadrangle.C.X,AQuadrangle.D.X)); Oy := min(min(AQuadrangle.A.Y,AQuadrangle.B.Y),min(AQuadrangle.C.Y,AQuadrangle.D.Y)); Fx := max(max(AQuadrangle.A.X,AQuadrangle.B.X),max(AQuadrangle.C.X,AQuadrangle.D.X)); Fy := max(max(AQuadrangle.A.Y,AQuadrangle.B.Y),max(AQuadrangle.C.Y,AQuadrangle.D.Y)); RQWidth := Fx-Ox; RQHeight := Fy-Oy;//--création d'une copie du bitmap d'origine BmpOrigin := TBitmap.Create; BmpOrigin.HandleType := bmDIB; BmpOrigin.PixelFormat := pf24Bit; BmpOrigin.Height := RQHeight; BmpOrigin.Width := RQWidth;//--création du bitmap final qui sera transféré à "result" BmpFinal := TBitmap.Create; BmpFinal.HandleType := bmDIB; BmpFinal.PixelFormat := pf24Bit; BmpFinal.Height := RQHeight; BmpFinal.Width := RQWidth; BmpFinal.Canvas.Brush.Color := BkColor; BmpFinal.Canvas.FillRect(rect(0,0,RQWidth,RQHeight));//--mise à l'échelle du bitmap d'origine par rapport au rectangle maitre BmpOrigin.Canvas.StretchDraw(rect(0,0,RQWidth,RQHeight),ABitmap);//--définir la taille des tableaux dynamiques SetLength(TabScanLine,BmpOrigin.Height); SetLength(TSLFinal,BmpFinal.Height);// transférer les données (pixels) dans chaque tableau For v:=0 to RQHeight-1 do begin // transférer les information de l'image dans les tableaux TabScanLine[v] := BmpOrigin.ScanLine[v]; TSLFinal[v] := BmpFinal.ScanLine[v]; end;//--Transférer les pixels au bon endroit DistAD := AQuadrangle.D.Y-AQuadrangle.A.Y; DistBC := AQuadrangle.C.Y-AQuadrangle.B.Y; DistAB := AQuadrangle.B.X-AQuadrangle.A.X; DistDC := AQuadrangle.C.X-AQuadrangle.D.X; {Pour chaque pixel, calcule le taux de positionnement de x et y} For v:=1 to BmpOrigin.Height-1 do begin TauxY := v / BmpOrigin.Height; PosYAD := AQuadrangle.A.Y-OY+(DistAD*TauxY); PosYBC := AQuadrangle.B.Y-OY+(DistBC*TauxY); For u := 1 to BmpOrigin.Width-1 do begin TauxX := u / BmpOrigin.Width; PosXAB := AQuadrangle.A.X-OX+(DistAB*TauxX); PosXDC := AQuadrangle.D.X-OX+(DistDC*TauxX); TmpX := PosXAB+(PosXDC-PosXAB)*TauxY; TmpY := PosYAD+(PosYBC-PosYAD)*TauxX; x := round(Int(TmpX)); y := Round(Int(TmpY)); xd := Round(Frac(TmpX)); yd := Round(Frac(TmpY)); {transfère les pixels au bon emplacement} TSLFinal[y,x] := TabScanLine[v,u]; //pour lever les "trous..." if (xd>0) and (x<BmpOrigin.Width-2) then TSLFinal[y,x+1] := TabScanLine[v,u]; if (yd>0) and (y<BmpOrigin.Height-2) then TSLFinal[y+1,x] := TabScanLine[v,u]; end; end;//--assigne le bitmap final au "result" result := TBitmap.create; Result.Assign(bmpFinal); bmpFinal.Free; BmpOrigin.free;end;mais on peut faire mieux en utilisant des pointeurs à la place des tableaux et en passant en 32bits
Merci CIREC, j'ai mis à jour la source d'après tes conseils d'optimisation (je n'avais pas pensé à regrouper les calculs redondants).Je serai intéressé par le 32bits, ça me permettrai de dessiner l'image déformé en mode "transparent". en ce qui concerne les pointeurs à la place des tableaux, il faudrait que je me penche un peu plus dessus :-)
Pour le recto verso : 2 TBitmap qui sont dessinés l'un derriere l'autre !Pour le transparent : en 24 bits, il suffit d'utiliser une transparent color avec une constant que tu définis...Je suis sur Embarcadero (newsgroup) pour la définir...DH
Pas mal !Un petit peu d'anti-aliasing sur les bords et c'est nikel !D'ailleurs ça serait particulièrement simple vu que tu connais les côtés à lisser ... Un petit flou léger sur les bords :)Cordialement, Bacterius !
Et plus que quatre points ?
Pourquoi tous mes messages sont supprimés ? D'abord sur l'horloge binaire, maintenant ici ?Est-ce moi qui bug ?Cordialement, Bacterius !
Ah excusez-moi j'avais pas vidé le cache, mes messages n'étaient pas apparents.Cordialement, Bacterius !
@Spatul:j'avais coché "verification des limite" dans un autre programme et l'avais conservé..cela dit, tu devrais définir les deux paramètres du tableau à deux demensions.SetLength(TSLFinal, BmpFinal.Height);sinon ça marche, quelques soucis de saturation et d'aliasing..original 8/10.bon courage
histoire de mettre mon grain de sel. J'avais fait la même chose, mais avec des calculs en réel et non dans les entiers.Ainsi, quand tu cherche le pixel de l'image de départ, tu peux "facilement" faire une interpolation des couleurs, surtout si on étire l'image.Sinon, c'est bien foutu..barbichette
ah, juste un point, j'avais pas regardé en détail...Dans ce genre de transformation, il vaut mieux faire les calculs à l'envers.Parcourir tous les pixels de l'image finale et regarder où il est dans l'image initiale.ainsi, on est sur qu'il n'y a pas de trou et c'est avec ce calcul qu'on utilise mon interpolation.Je vais essayer de retrouver l'algo en inversant les calculs.
Se souvenir du profil
Mot de passe oublié ? / Activation de compteCréer un compte
1 873 499 membres 33 nouveaux aujourd'hui 16 151 membres club