IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaFX Discussion :

Comment dessiner sur une image


Sujet :

JavaFX

  1. #1
    Membre expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 076
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    Par défaut Comment dessiner sur une image
    Voilà

    J'ai une image que j'affiche dans un ImageView avec différent niveau de zoom et je voudrais ajouter dessus:
    • Des textes qui ne seront pas affecté par le zoom. C'est à dire que quelque soit le niveau de zoom la taille des caractère est toujours la même
    • Des contours (polygones non rempli) dont le trait à toujours la même épaisseur quelque soit le niveau de zoom


    J'ai vu que la classe Canvas permet de dessiner mais je n'arrive pas à trouver d'interaction avec la cleasse Image pour réaliser ce que je veux faire.
    Il y a des jours où j'éprouve une haine profonde envers microsoft et Apple c'est pas mieux
    Mon modeste site et mes modestes oeuvres sont
    Rémi

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Je trouve que c'est mal fichu de ce coté-là par rapport a Java2D.

    Alors, à notre droite, nous avons :
    Canvas -> GraphicsContext -> PixelWriter
    Le GraphicsContext est un peu l’équivalent du Graphics2D dans Java2D a ceci près qu'il conserve la liste de commande de dessin. Donc attention fuite mémoire potentielle ou trou de perfs si on ne le nettoie pas de temps a autres.
    Le PixelWriter c'est un peu l’équivalent du WritableRaster dans Java2D, c'est ce qui permet d’accéder aux données brutes de l'image en écriture.

    Tandis qu'à notre gauche, nous avons :

    WritableImage -> PixelWriter
    Donc on ne peut pas utiliser l'API de dessin de haut niveau sur WritableImage, on peut uniquement utiliser que l'API de dessin de bas niveau avec des recopies de buffers ou trucs genre setRGB(). Cela veut dire que si tu veux utiliser des choses genre drawLine() etc, il faut de toutes manières utiliser Canvas (le canevas n'a pas besoin d’être forcement attaché à une scène, il peut être offscreen).

    Ensuite pour convertir un Canvas en Image, le plus simple est d'utiliser sa méthode snapshot() et de conserver l'image retournée histoire de la repasser en paramètre lors des appels ultérieurs pour éviter d'en créer une nouvelle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    WritableImage image = null;
    Canvas canvas = [...]
     
     
    [...]
     
    image = canvas.snapshot(null, image);
    l'ennui c'est qu'il faut que la pile des commandes du GraphicsContext ait été rendue ce qui peut être gênant si tu génères le contenu du Canvas dans un thread séparé. D'un autre coté si tu comptes afficher l'image, tu peux tout aussi bien afficher directement le Canvas a l’écran. Gaffe cependant à ce qu'il n'y ait pas de conflit de threads entre l'affichage et les appels des commandes.

    Note : accessoirement, JFree (editeur de JFreeChart) propose la lib FXGraphic2D qui permet d'utiliser Java2D pour dessiner sur un Graphics2D contenant un GraphicsContext d'un Canvas. Ça peut être utile comme solution intermédiaire quand on a pas trop le temps de convertir le code de dessin depuis Java2D vers JavaFX.

    L'alternative consiste bien sur a conserver toute la pile de rendu Java2D et de convertir la BufferedImage Swing en Image JavaFX pour l'affichage via la fonction utilitaire de conversion. Resp pour SWT.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Membre expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 076
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    Par défaut
    Alors en fait j'ai utilisé une autre solution qui consiste à superposer un Canvas de la même taille que mon image.

    Je défini une région qui contient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    private ImageView vueCarte = new ImageView();
    private Canvas decors = new Canvas();
     
    private Region mapArea = new Region() {
    		{
    			getChildren().add(vueCarte);
    			getChildren().add(decors);
    		}
    	};
    Ensuite dans start je déclare pour l'image et le canvas les fonctions de réactions à la souris
    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
     
    public void start(Stage primaryStage) {
    		vueCarte.setImage(fondDeCarte.getImage());
     
    		final Rectangle2D viewport = new Rectangle2D(0, 0, 500, 500);
    		vueCarte.setViewport(viewport);
    		vueCarte.setOnMousePressed(this::handleMousePressed);
    		vueCarte.setOnMouseDragged(this::handleMouseDragged);
    		vueCarte.setOnMouseMoved(this::handleMouseMoved);
    		vueCarte.setOnScroll(this::handleZoom);
    		vueCarte.getTransforms().add(scale);
    		Platform.runLater(() ->
     
    		{
    			mapArea.widthProperty().addListener(this::mapAreaSizeChanged);
    			mapArea.heightProperty().addListener(this::mapAreaSizeChanged);
    		});
    		decors.setOnMousePressed(this::handleMousePressed);
    		decors.setOnMouseDragged(this::handleMouseDragged);
    		decors.setOnMouseMoved(this::handleMouseMoved);
    		decors.setOnScroll(this::handleZoom);
    		decors.getTransforms().add(scale);		
    		primaryScene = new Scene(vueRoot, 500, 500);
    		primaryStage.setTitle("Feu de Forêt v1.0");
    		primaryStage.setScene(primaryScene);
    		primaryStage.show();		
    		corrigeLocation(0, 0);
     
    	}
    Quand je change le zoom je redessine simplement mon Canvas de la façon suivante
    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
     
    private void MajDecors(boolean relief) {
    		// préparation relief
    		decors.setWidth(scenario.getLeTerrain().getLargeur());
    		decors.setHeight(scenario.getLeTerrain().getHauteur());
    		GraphicsContext gc = decors.getGraphicsContext2D();
    		if (relief) {
    			gc.setStroke(javafx.scene.paint.Color.CRIMSON);
                            //ajustement de la taille du trait au niveau de zoom de manière à ce qu'il présente toujours la même épaisseur
    			gc.setLineWidth(zoom);
    			ArrayList<Relief> crtRelief = scenario.getLeTerrain().getReliefs();
     
    			for (Relief rel : crtRelief) {
    				double[] xr = rel.getLesX(false);
    				double[] yr = rel.getLesY(false);
    				gc.strokePolygon(xr, yr, xr.length);
    			}
    		}
    	}
    Ca fonctionne relativement bien
    Il y a des jours où j'éprouve une haine profonde envers microsoft et Apple c'est pas mieux
    Mon modeste site et mes modestes oeuvres sont
    Rémi

Discussions similaires

  1. comment dessiner sur une image
    Par baracouda dans le forum Graphisme
    Réponses: 2
    Dernier message: 26/05/2006, 00h21
  2. Dessiner sur une image
    Par alex6891 dans le forum Java ME
    Réponses: 1
    Dernier message: 16/04/2006, 02h45
  3. Déplacer, zoomer, dessiner (sur) une image
    Par charlito dans le forum 2D
    Réponses: 4
    Dernier message: 22/02/2006, 01h58
  4. Comment écrire sur une image, dans un cadre ?
    Par Nutrino dans le forum Balisage (X)HTML et validation W3C
    Réponses: 7
    Dernier message: 20/05/2005, 00h55
  5. [Servlet] [Image] Dessiner sur une image
    Par gaia_dev dans le forum 2D
    Réponses: 5
    Dernier message: 01/09/2004, 17h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo