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 :

Problème de redimention d'image


Sujet :

JavaFX

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2020
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2020
    Messages : 11
    Points : 5
    Points
    5
    Par défaut Problème de redimention d'image
    Bonjour, je développe une applicaion de visioneuse, et je souhaiterai pouvoir zoomer sur l'image affichée ainsi que de pouvoir me déplacer dedans... Mon problème est quand lorsque j'utilise le zoom, ça redimentionne ma Région au lieux de mon image.. Je vous joint quelques captures d'écran pour vous expliquer :
    Nom : 1.JPG
Affichages : 883
Taille : 89,5 Ko
    L'image qui est affichée au début.
    Nom : 2.JPG
Affichages : 852
Taille : 65,3 Ko
    L'image une fois que j'ai zoomé
    Nom : 3.JPG
Affichages : 849
Taille : 66,6 Ko
    L'image une fois que j'ai dézoomé.

    Le déplacement dans l'image fonctionne mais le zoom je souhaiterai que la zone de l'image reste fixe et que ce soit l'image qui se zoom et pas l'inverse.

    J'utilise javaFx, j'ai un fichier FXML qui contient pour la zone d'image, un Pane, qui lui comprend une région et une imageView.

    Mon code qui gère le zoom :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    visioneusePrincipal.setImage(image);
                    final Rectangle2D viewport = new Rectangle2D(0, 0, 0, 0);
                    visioneusePrincipal.setViewport(viewport);
                    visioneusePrincipal.setOnMousePressed(this::handleMousePressed);
                    visioneusePrincipal.setOnMouseDragged(this::handleMouseDragged);
                    visioneusePrincipal.setOnScroll(this::handleZoom);
                    visioneusePrincipal.getTransforms().add(scale);
                    Platform.runLater(() -> {
                        mapArea.widthProperty().addListener(this::mapAreaSizeChanged);
                        mapArea.heightProperty().addListener(this::mapAreaSizeChanged);
                    });
    Et les fonctions :

    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     
     private void handleMousePressed(MouseEvent e) {
            startX = e.getX();
            startY = e.getY();
        }
     
        private void handleMouseDragged(MouseEvent e) {
     
            double draggedDistanceX = startX - e.getX();
            double draggedDistanceY = startY - e.getY();
     
            startX = e.getX();
            startY = e.getY();
     
            double viewWidth = mapArea.getWidth() * 1 / zoom;
            double viewHeight = mapArea.getHeight() * 1 / zoom;
     
            final Rectangle2D viewport = visioneusePrincipal.getViewport();
            double curMinX = viewport.getMinX();
            double curMinY = viewport.getMinY();
     
            double newMinX = curMinX + draggedDistanceX;
            double newMinY = curMinY + draggedDistanceY;
            newMinX = clamp(newMinX, 0, Math.max(0, visioneusePrincipal.getImage().getWidth() - viewWidth));
            newMinY = clamp(newMinY, 0, Math.max(0, visioneusePrincipal.getImage().getHeight() - viewHeight));
            visioneusePrincipal.setViewport(new Rectangle2D(newMinX, newMinY, viewWidth, viewHeight));
            System.out.printf("%f x %f \t %f x %f%n", newMinX, newMinY, visioneusePrincipal.getImage().getWidth(), visioneusePrincipal.getImage().getHeight());
        }
     
        double clamp(double min, double value, double max) {
            double result = Math.max(min, value);
            result = Math.min(result, max);
            return result;
        }
     
        private void mapAreaSizeChanged(Observable o) {
            double viewWidth = mapArea.getWidth() * 1 / zoom;
            double viewHeight = mapArea.getHeight() * 1 / zoom;
            final Rectangle2D viewport = visioneusePrincipal.getViewport();
            if (viewport.getWidth() != viewWidth || viewport.getHeight() != viewHeight) {
                double newMinX = viewport.getMinX();
                double newMinY = viewport.getMinY();
                newMinX = clamp(newMinX, 0, Math.max(0, visioneusePrincipal.getImage().getWidth() - viewWidth));
                newMinY = clamp(newMinY, 0, Math.max(0, visioneusePrincipal.getImage().getHeight() - viewHeight));
                visioneusePrincipal.setViewport(new Rectangle2D(newMinX, newMinY, viewWidth, viewHeight));
            }
        }
     
        private double zoom = 1.0;
        private Scale scale = new Scale(zoom, zoom);
        private static final double MIN_ZOOM = 0.5;
        private static final double MAX_ZOOM = 2.0;
     
        private void handleZoom(ScrollEvent event) {
            double delta = event.getDeltaY();
            double newZoom = zoom;
            if (delta < 0) {
                newZoom /= 2;
            }
            if (delta > 0) {
                newZoom *= 2;
            }
            newZoom = clamp(MIN_ZOOM, newZoom, MAX_ZOOM);
            if (newZoom == zoom) {
                return;
            }
            zoom = newZoom;
            System.out.printf("Zoom: %f%n", zoom);
            scale.setX(zoom);
            scale.setY(zoom);
            double viewWidth = mapArea.getWidth() * 1 / zoom;
            double viewHeight = mapArea.getHeight() * 1 / zoom;
            final Rectangle2D viewport = visioneusePrincipal.getViewport();
            if (viewport.getWidth() != viewWidth || viewport.getHeight() != viewHeight) {
                double newMinX = viewport.getMinX();
                double newMinY = viewport.getMinY();
                newMinX = clamp(newMinX, 0, Math.max(0, visioneusePrincipal.getImage().getWidth() - viewWidth));
                newMinY = clamp(newMinY, 0, Math.max(0, visioneusePrincipal.getImage().getHeight() - viewHeight));
                visioneusePrincipal.setViewport(new Rectangle2D(newMinX, newMinY, viewWidth, viewHeight));
            }
        }
    Merci beaucoup !

  2. #2
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 856
    Points : 22 885
    Points
    22 885
    Billets dans le blog
    51
    Par défaut
    Ca serait bien d'avoir le FXML.
    Pour ce que j'en vois tu utilises une transformation de zoom (variable scale() sur setTransform()). Pourquoi ne pas tout simplement ne pas utiliser les fitWidth et fitHeight de ton ImageView ?
    Et question conne mais pourquoi ne pas utiliser un ScrollPane ?

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2020
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2020
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par bouye Voir le message
    Et question conne mais pourquoi ne pas utiliser un ScrollPane ?
    Bonjour déjà merci de ta réponse. Pour ce qui est du ScrollPane, tu parles pour se déplacer dans l'image ? Parce que si c'est le cas le déplacement du click plus déplacement dans l'image est fonctionnel.

    Citation Envoyé par bouye Voir le message
    Pour ce que j'en vois tu utilises une transformation de zoom (variable scale() sur setTransform()). Pourquoi ne pas tout simplement ne pas utiliser les fitWidth et fitHeight de ton ImageView ?
    Je ne sais pas, je débute avec javaFx et j'ai fais des recherches sur internet et je suis tombé sur cette méthode que j'ai essayé d'appliquer dans mon cas. Peux-tu m'en dire plus sur ses 2 méthodes s'il te plait ?

    Citation Envoyé par bouye Voir le message
    Ca serait bien d'avoir le FXML.
    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
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.control.TextField?>
    <?import javafx.scene.control.TreeView?>
    <?import javafx.scene.image.Image?>
    <?import javafx.scene.image.ImageView?>
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.layout.Pane?>
    <?import javafx.scene.layout.Region?>
     
    <AnchorPane prefHeight="750.0" prefWidth="1300.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="historia.visioneuse.controler.VisioneuseController">
       <children>
          <ImageView id="blason" fitHeight="150.0" fitWidth="200.0" layoutX="1145.0" layoutY="79.0" pickOnBounds="true" preserveRatio="true">
             <image>
                <Image url="@../../../img/blason.jpg" />
             </image>
          </ImageView>
          <TreeView fx:id="selectionTreeView" layoutX="27.0" layoutY="14.0" prefHeight="600.0" prefWidth="200.0" AnchorPane.leftAnchor="15.0" AnchorPane.topAnchor="50.0" />
          <Pane layoutX="300.0" prefHeight="40.0" prefWidth="700.0" AnchorPane.leftAnchor="300.0" AnchorPane.rightAnchor="300.0" AnchorPane.topAnchor="0.0">
             <children>
                <Button layoutX="14.0" layoutY="5.0" mnemonicParsing="false" prefHeight="30.0" prefWidth="117.0" text="Rechercher" />
                <TextField alignment="CENTER" layoutX="161.0" layoutY="5.0" prefHeight="30.0" prefWidth="499.0" promptText="Votre recherche..." />
             </children>
          </Pane>
          <Pane layoutX="1144.0" layoutY="361.0" prefHeight="182.0" prefWidth="122.0">
             <children>
                <Button mnemonicParsing="false" onAction="#handleHelpButton" prefHeight="26.0" prefWidth="122.0" text="Aide" />
                <Button layoutY="38.0" mnemonicParsing="false" onAction="#handleConfig" prefHeight="26.0" prefWidth="122.0" text="Configuration" />
                <Button accessibleHelp="Bonjour" accessibleText="Test" layoutY="81.0" mnemonicParsing="false" onAction="#handleAcceuil" prefHeight="26.0" prefWidth="122.0" text="Accueil" />
                <Button layoutY="118.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="122.0" text="Sauvegarde" />
                <Button layoutY="156.0" mnemonicParsing="false" onAction="#handleFermerSession" prefHeight="26.0" prefWidth="122.0" text="Fermer session" />
             </children>
          </Pane>
          <Pane layoutX="376.0" layoutY="50.0" prefHeight="40.0" prefWidth="548.0">
             <children>
                <Button layoutY="8.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="130.0" text="Marquer cette page" />
                <Button layoutX="140.0" layoutY="8.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="130.0" text="Ajouter mention" />
                <Button layoutX="276.0" layoutY="8.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="130.0" text="Imprimer / Envoyer" />
                <Button layoutX="412.0" layoutY="8.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="130.0" text="Plein écran" />
             </children>
          </Pane>
          <Pane id="BouttonNavigation" layoutX="550.0" layoutY="734.0" prefHeight="30.0" prefWidth="200.0">
             <children>
                <Button maxWidth="200.0" mnemonicParsing="false" onAction="#PreviewButton" prefHeight="25.0" prefWidth="92.0" />
                <Button layoutX="100.0" maxWidth="200.0" mnemonicParsing="false" onAction="#NextButton" prefHeight="25.0" prefWidth="92.0" />
             </children>
          </Pane>
          <Pane fx:id="zoneImage" layoutX="310.0" layoutY="10.0" prefHeight="622.0" prefWidth="838.0" AnchorPane.leftAnchor="276.0" AnchorPane.topAnchor="90.0">
             <children>
                <Region fx:id="mapArea" prefHeight="622.0" prefWidth="838.0" />
                <ImageView fx:id="visioneusePrincipal" fitHeight="622.0" fitWidth="838.0" pickOnBounds="true" preserveRatio="true" />
             </children>
          </Pane>
       </children>
    </AnchorPane>
    Merci beaoucoup

  4. #4
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 856
    Points : 22 885
    Points
    22 885
    Billets dans le blog
    51
    Par défaut
    Pas que pour les déplacements, le ScrollPane offre un espace de clip de la vue via son viewport qui est géré automatiquement; une zone de clip ce qui manque dans ton code.

    Ton ImageView nommée visioneusePrincipal devrait être placée dans un conteneur parent qui devrait disposer d'un rectangle de clip pour l’empêcher de se redimensionner lorsque tu appliques des mises a l’échelle sur visioneusePrincipal.

    ImageView dispose des propriétés fitWidth et fitHeight pour adapter l'image visionnée a de nouvelle dimensions d'affichage ce qui permet en général d’éviter de faire une mise a l’échelle (soit via la propriété scale, soit via une transformation comme toi) sur le nœud.

    Donc en gros tu dois avoir :

    • image - l'Image a afficher.
    • visioneusePrincipal - l'ImageView, le controle qui affiche l'image.
    • viewport - un Rectangle définissant la vue c-a-d la zone de l'image a afficher dans visioneusePrincipal.
    • le conteneur parent qui doit afficher visioneusePrincipal.
    • clip - un Rectangle qui va restreindre le contenu affiche dans le parent. Les dimensions de ce clip doivent donc correspondre aux dimensions logiques du parent (c-a-d l'espace qu'il est sensé occupe a l’écran).



    Après c'est pour une première approche. Y a moyen de combiner le viewport et le clip au niveau de visioneusePrincipal mais ça demande plus de réflexion et de calculs.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2020
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2020
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par bouye Voir le message
    Pas que pour les déplacements, le ScrollPane offre un espace de clip de la vue via son viewport qui est géré automatiquement; une zone de clip ce qui manque dans ton code.
    Mais du coup il y aura des barres de scroll non ? Je veux éviter ça justement.

    Citation Envoyé par bouye Voir le message
    Ton ImageView nommée visioneusePrincipal devrait être placée dans un conteneur parent qui devrait disposer d'un rectangle de clip pour l’empêcher de se redimensionner lorsque tu appliques des mises a l’échelle sur visioneusePrincipal.
    Un région n'est pas la même chose ?

    Citation Envoyé par bouye Voir le message
    ImageView dispose des propriétés fitWidth et fitHeight pour adapter l'image visionnée a de nouvelle dimensions d'affichage ce qui permet en général d’éviter de faire une mise a l’échelle (soit via la propriété scale, soit via une transformation comme toi) sur le nœud.
    Juste avec ses deux propriétés un zoom fonctionnerai ? (:

    Citation Envoyé par bouye Voir le message
    Donc en gros tu dois avoir :

    • image - l'Image a afficher.
    • visioneusePrincipal - l'ImageView, le controle qui affiche l'image.
    • viewport - un Rectangle définissant la vue c-a-d la zone de l'image a afficher dans visioneusePrincipal.
    • le conteneur parent qui doit afficher visioneusePrincipal.
    • clip - un Rectangle qui va restreindre le contenu affiche dans le parent. Les dimensions de ce clip doivent donc correspondre aux dimensions logiques du parent (c-a-d l'espace qu'il est sensé occupe a l’écran).
    Le viewport et le clip sont des élément FXML ? Car je ne trouve pas réelement leurs provenance..

    J'ai essayé de me renseigner en vain aujourd'hui. Je n'ai toujours pas réussi à faire ce fichu zoom. Je suis souvent tomber sur l'utilsiation d'une Region mais ne fonctionne toujours pas malgré mes nombreux essais..

    PS : Je suis désolé je débute seulement et j'ai pas forcément toutes les conaissances nécéssaires.

  6. #6
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 856
    Points : 22 885
    Points
    22 885
    Billets dans le blog
    51
    Par défaut
    Citation Envoyé par Ouisticrabe Voir le message
    Mais du coup il y aura des barres de scroll non ? Je veux éviter ça justement.
    l'affichage des barres de scroll est gerable via les policy :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    scrollPane.setHbarPolicy(ScrollBarPolicy.NEVER);
    scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER);

    Citation Envoyé par Ouisticrabe Voir le message
    Un région n'est pas la même chose ?
    Une region c'est un noeud basique dans lequel il faut tout faire a mano y compris la mise en page.


    Citation Envoyé par Ouisticrabe Voir le message
    Juste avec ses deux propriétés un zoom fonctionnerai ? (:
    Elles sont un peu faites pour... Et si tu faisais un petit programme de test a cote pour voir comment ca marche ? C'est comme ca qu'on apprend.

    Citation Envoyé par Ouisticrabe Voir le message
    Le viewport et le clip sont des élément FXML ? Car je ne trouve pas réelement leurs provenance..
    Le viewport (le tien) provient de ton code...
    Le clip est une propriété standard donc oui tu peux le définir dans le FXML même s'il faudra faire de la manipulation pour le mettre aux bonnes tailles dans le contrôleur.

    Citation Envoyé par Ouisticrabe Voir le message
    J'ai essayé de me renseigner en vain aujourd'hui. Je n'ai toujours pas réussi à faire ce fichu zoom. Je suis souvent tomber sur l'utilsiation d'une Region mais ne fonctionne toujours pas malgré mes nombreux essais..
    Region c'est un noeud basique (c'est l'equivalent d'un simple <div> en HTML donc faut tout programmer soit meme, ce qui rend la chose moins abordable quand on debute du coup.

    Citation Envoyé par Ouisticrabe Voir le message
    PS : Je suis désolé je débute seulement et j'ai pas forcément toutes les conaissances nécéssaires.
    C'est pas bien grave, il fait bien commencer un jour...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 13
    Dernier message: 23/12/2004, 18h01
  2. Problème de réaffichage d'image
    Par benj63 dans le forum C++Builder
    Réponses: 2
    Dernier message: 09/12/2004, 09h41
  3. [débutant] problème de lecture d'image
    Par shura dans le forum OpenGL
    Réponses: 16
    Dernier message: 03/07/2004, 18h05
  4. Problème de nb d'images par seconde
    Par Francky033 dans le forum DirectX
    Réponses: 7
    Dernier message: 17/04/2004, 10h37
  5. Problème de mémoire Affichage images
    Par Repti dans le forum C++Builder
    Réponses: 6
    Dernier message: 29/03/2004, 20h06

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