Traiter une image en tache de fond

Résolu
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 - 12 janv. 2008 à 20:24
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 - 21 janv. 2008 à 08:51
Bonjour,

Je suis en train de développer un logiciel de cartographie qui utilise des cartes au format bmp (elle font 2000 par 2000 pixels). elles sont assemblées entre elle pour former une carte bien plus grande (1Go de taille).

pour afficher la carte sur un TImage, je détermine quelles sont les fichiers utilisé, je les lit un par un dans un TImage temporaire, et pour chaque fichier, je fait une boucle For pour transferer les points du TImage temporaire vers le TImage de la Form.

Le probléme, c'est que j'aimerais calculer le tracé dans un TImage de trace de même dimension que le TImage de la form, puis transférer cette image de trace dans celle de la form. Je pourrais ainsi mettre dans la fonction Image.Paint, une fonction de transfert rapide de l'image de trace vers la form plutot que de tout recalculer.

je vous met la fonction de transfert de TImage temporaire vers le TImage de la form

xcc1,ycc1 représente le coin supérieur gauche de l'image TImage temporaire
xdd1,ydd1 représente le coin inférieur droit de l'image TImage temporaire

for i:=xcc1 to xdd1 do
                      begin
                        Application.ProcessMessages;

                        for j:=ydd1 to ycc1 do
                          begin
                            // coordonnée du point i,j (coordonnées écran) en coordonnées xi,yi (coordonnées générales)
                            {xi:=trunc((i*zoom)+xo1);
                            yi:=trunc(yo1-(j*zoom));
                            // xi,yi (coordonnées générales) en coordonnées xi,yi  (coordonnées image carte)
                            xi:=xi-xcarte*CT_LongCarte;
                            yi:=CT_LongCarte-(yi-ycarte*CT_LongCarte);
                            }
                            xi:=trunc((i*zoom)+xo1-xcarte*CT_LongCarte);
                            yi:=trunc(CT_LongCarte-(yo1-(j*zoom)-ycarte*CT_LongCarte));
                            couleur:=FMain.ImageTemp.Canvas.Pixels[xi,yi]; // on prend la couleur d'image temp
                            FMain.ImageTrace.Canvas.Pixels[i,j]:=couleur; // on écrit la couleur
                          end; // fin j
                      end; // fin i  

Ce type de fonctionnement est très lent et j'aimerais optimiser tout ca mais je ne vois pas comment faire.

Si quelqu'un pourrait me dire s'il existe une fonction permettant de copier plus rapidement une zone rectangulaire d'une image vers une autre. Et par la même, comment transférer une image vers une autre.

Merci pour vos réponse

Oniria

5 réponses

Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
20 janv. 2008 à 20:01
Voici un exemple qui fait une copie en agrandissant 2x

Il faut 2 TImage et 1 TButton
Charge un Bitmap dans Image1 (assez grand plus de 200 x 200)

Procedure TForm1.Button1Click(Sender:
TObject);
Var BmpDest : TBitmap;
Begin
  BmpDest := TBitmap.Create;
  Try
    {prépare le
Bitmap de destination}
    BmpDest.Width := 200;
    BmpDest.Height := 200;
    {Meilleur
qualité}
    SetStretchBltMode(BmpDest.Canvas.Handle, HALFTONE);

     {Effectue une copie avec Stretch}
    StretchBlt(BmpDest.Canvas.Handle, //Handle de
destination
      0, 0, 200, 200, //Rectangle de destination
(correspond à BmpDest)
      Image1.Picture.Bitmap.Canvas.Handle,
//Handle Source
      200, 200, // Top,Left de la partie a copier
      100, 100, // Width Height de la partie a copier
      {ce qui fait un carré de 100 de coté
}
      srcCOPY);
    {et on affiche
le résultat}
    Image2.Picture.Bitmap.Assign(BmpDest);

  Finally
    BmpDest.Free;

   End ;
End;
<center>Highlighted with Pas2HTML </center>
Il est également possible de cibler un rectangle bien précis avec
ScanLine mais c'est un peut plus compliqué et surtout pas utile pour ce
que tu veux faire ici

@+
Cirec

<hr siz ="" />
3
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 3
21 janv. 2008 à 08:51
Bonjour,

Merci beaucoup, cette méthode marche super bien, c'est mieux que ce que j'ai finalement fait pour l'impression d'une image. Dans le cas du trace de la carte à l'écran, j'avais besoin de copier des zones d'autres images avec un facteur de zoom et non une image à adapter, la copie était plus difficile.

En tout cas, merci beaucoup, ca m'enleve une sacrée épine du p...programme :)

Comme les cartes ont été récupéré sur google, je ne peut pas les mettre sur le site (droit d'auteur), mais je vais mettre ce petit programme sur delphifr avec une explication du fonctionnement des cartes et de leurs créations.

Oniria
1
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
12 janv. 2008 à 21:48
Salut,

il est très utile de connaitre l'utilisation de ScanLine
mais pour ton cas précis je te conseil un transfert par bloc qui est la méthode la plus rapide ...

Voir BitBlt, StretchBlt
BitBlt( CanvasDest.Handle, PosDX, PosDY, Width, Height, CanvasSource.Handle, PosSX, PosSY, srcCOPY);

PosDX, PosDY : coin suppérieur Gauche de destination
Width, Height : Taille
PosSX, PosSY :  coin suppérieur Gauche de la source

 
@+
Cirec

<hr siz="" />
0
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 3
13 janv. 2008 à 21:28
Bonjour à vous deux,

Merci d'avoir répondu aussi vite, je vais tester ce que vous m'avez conseillé et je vous donnerais une réponse.

Oniria
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 3
20 janv. 2008 à 18:59
Bonjour,

Pour répondre, je ne peut pas utiliser scanline car je doit faire une mise à l'échelle de l'image. (en agrandissement ou en réduction). J'ai compensé le systéme en dévalidant la barre d'outils et l'image de manière à empécher toutes les intéractions de l'utilisateur pendant le calcul (je ne le fais que pour un déplacement ou un zoom). Le calcul se fait dans un Bitmap temporaire. Et l'événement OnPaint du TImage de la Form, je fait juste une assignation.

Oniria
0
Rejoignez-nous