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

2D Java Discussion :

zoom sur image


Sujet :

2D Java

  1. #1
    HiT
    HiT est déconnecté
    Débutant
    Inscrit en
    Juillet 2004
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 74
    Points : 20
    Points
    20
    Par défaut zoom sur image
    Bonjour,
    j'ai éffectué de nombreuses recherches sur ce forum ce qui m'a permis de faire le code suivant.
    J'ai une image que je souhaite zoomer. Le niveau de zoom dépend de la valeur que l'on donne à un JSlider (un curseur), qui n'a que les valeurs 0,1,2,3.
    Dés que la position de ce curseur change voisi ce qui est éffecuté :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	public void stateChanged(ChangeEvent e) {
    				JSlider curseur = (JSlider)e.getSource();
    				BufferedImage monImageB = toBufferedImage(monImage);
    				scale (monImageB,(curseur.getValue()));			
     
    			}});
    toBufferedImage permet simplement de caster une image en bufferedimage.
    Quand à sclae, elle permet normalement de changer la taille de l image, voila le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	public static BufferedImage scale(BufferedImage bi, double scaleValue) {
    		  int width = (int) (bi.getWidth() * scaleValue);
    		  int height = (int) (bi.getHeight() * scaleValue);
    		  BufferedImage biNew = new BufferedImage( width, height, bi.getType()); 
    		  Graphics2D graphics = biNew.createGraphics();
    		  graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    		  graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
    		  graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
    		  graphics.drawImage(bi, 0, 0, width, height, null);
    		  graphics.dispose();
    		  return biNew;
    		}
    aucun problème à la compilation, mais lorsque je le lance, et que je bouge le curseur, rien ne se passe car je ne sais pas faire réafficher la nouvelle Bufferedimage généré... je suis débutant dsl
    Peut etre que la facon dont j'initialise mon curseur peut vous aider:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        curseur.setMajorTickSpacing(1);
    		curseur.setMinorTickSpacing(1);
    		curseur.setPaintLabels(true);
    		curseur.setPaintTicks(true);
    		maCarte.add(curseur,BorderLayout.EAST);
    		curseur.setMajorTickSpacing(1);
    		curseur.setMinorTickSpacing(1);
    		curseur.setPaintLabels(true);
    		curseur.setPaintTicks(true);
    		maCarte.add(curseur,BorderLayout.EAST);
    merci de votre aide.

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 851
    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 851
    Points : 22 863
    Points
    22 863
    Billets dans le blog
    51
    Par défaut
    Il manque peut-etre un repaint() et/ou une re-affectation de la reference de l'image courante (qui doit etre dessinee dans le panel) qq part.

    Une petite remarque : zoomer l'image elle-meme pour en creer une nouvelle est (en general*) peu utile et peut rapidement mener a des pb de memoire (si on zoome trop la nouvelle image creee est enorme). Il peut-etre plus judicieux d'utiliser la primitive scale() ou une AffineTransform.getScaleInstance() directement sur le graphics d'affichage du panel.

    *Peut-etre est-ce necessaire dans le cas de ton appli.

  3. #3
    HiT
    HiT est déconnecté
    Débutant
    Inscrit en
    Juillet 2004
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 74
    Points : 20
    Points
    20
    Par défaut
    en fait non je voudrais juste le code pour afficher une image a partir d'un jpeg et ensuite pouvoir la zoomer...
    merci

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 851
    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 851
    Points : 22 863
    Points
    22 863
    Billets dans le blog
    51
    Par défaut
    Mais si, mais si, je t'assure tu n'as a priori absolument aucun besoin de creer une nouvelle image a la taille zoomee.

    Il n'y a besoin de faire le zoom que la dans surcharge de paintComponent() et avec les methodes indiquees :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    g2d.setRenderingHint(...);
    g2d.drawImage(image, 0, 0, (int)(image.getWidth()*sx), (int)(image.getHeight()*sy), null);
    Ou :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    g2d.setRenderingHint(...);
    g2d.scale(sx, sy);
    g2d.drawImage(image, 0, 0, null);
    g2d.scale(-sx, -sy);
    Ou :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    g2d.setRenderingHint(...);
    g2d.transform(scaleTransform);
    g2d.drawImage(image, 0, 0, null);
    g2d.transform(scaleTransform.createInverse());
    Note : si l'image doit etre centree dans le panel un petit calcul tres simple s'impose pour x et y a la place de 0, 0. Rien de bien critique par rapport a la creation d'une nouvelle image plus grosse.

    Si le composant est dans un scroll pane, il peut etre egalement necessaire de modifier la taille preferree du composant en fonction du facteur de zoom selectionne. Quelques chose dans le genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public void stateChanged(ChangeEvent e) { 
      JSlider curseur = (JSlider)e.getSource(); 
      int scale = curseur.getValue();
      Dimension size = new Dimension(image.getWidth()*scale, image.getHeight()*scale);
      map.setSize(size);
      map.setPreferredSize(size);
      map.repaint();
    }
    Concernant l'initialisation de ta variable curseur, mis a part le fait que tu fais 2 fois la meme chose d'affilee il ne semble rien n'y avoir de bizarre.

    EDIT - bon bref comme je disais precedement, tu appeles scale() mais tu ne sauvegardes l'image retournee nulle part et tu ne fais aucun appel a repaint().

  5. #5
    HiT
    HiT est déconnecté
    Débutant
    Inscrit en
    Juillet 2004
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 74
    Points : 20
    Points
    20
    Par défaut
    merci
    j'ai essayé de suivre tes conseils
    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
    package manu;
     
     
    import java.awt.*;
    import java.awt.geom.AffineTransform;
    import java.awt.image.AffineTransformOp;
    import java.awt.image.BufferedImage;
     
    import javax.swing.*;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
     
    public class Map extends JFrame {
     
    	//Variables d'instance
    	protected JPanel maCarte;
    	protected Image monImage;
    	BufferedImage image;
    	JSlider curseur = new JSlider(JSlider.VERTICAL,1,3,1);
    	//Constructeurs
    	public Map() {
    		//Initialisation du JPanel
    		maCarte = new JPanel();
    		// Lecture de l'image par le tookit par défaut
    		monImage = Toolkit.getDefaultToolkit().getImage("carteIHM.jpg");
    		image = toBufferedImage(monImage); 
    		//Ajout du contenu
    		maCarte.setLayout(new BorderLayout());
    		maCarte.add(new MapPane(monImage),BorderLayout.CENTER);
    		curseur.setMajorTickSpacing(1);
    		curseur.setMinorTickSpacing(1);
    		curseur.setPaintLabels(true);
    		curseur.setPaintTicks(true);
    		maCarte.add(curseur,BorderLayout.EAST);
    		curseur.addChangeListener(new ChangeListener(){
     
    			public void stateChanged(ChangeEvent e) {
    				  JSlider curseur = (JSlider)e.getSource();
    				  int scale = curseur.getValue();
    				  scale(image,scale,scale);
    				  Dimension size = new Dimension(image.getWidth()*scale, image.getHeight()*scale);
    				  maCarte.setSize(size);
    				  maCarte.setPreferredSize(size);
    				  maCarte.repaint();
    				}});
    	}
     
    	//Accesseurs
    	public JPanel getmap() {
    		return maCarte;
    	}
     
    	public void scale(BufferedImage image, double sx,double sy) {
    		Graphics2D g2 = image.createGraphics(); 
    		g2.drawImage(image, 0, 0, (int)(image.getWidth()*sx), (int)(image.getHeight()*sy), null); 
    	}
     
     
    	BufferedImage toBufferedImage(Image image) {
     
            if( image instanceof BufferedImage ) {
     
                    return( (BufferedImage)image );
            } else {
     
                    image = new ImageIcon(image).getImage();
     
                    BufferedImage bufferedImage = new BufferedImage(
                                                          image.getWidth(null),
                                                          image.getHeight(null),
                                                          BufferedImage.TYPE_INT_RGB );
                    Graphics g = bufferedImage.createGraphics();
                    g.drawImage(image,0,0,null);
                    g.dispose();
                    return( bufferedImage );
            } 
    }
    }
    mais rien ne se passe, l'image ne change pas de dimensions :'(
    je comprends rien à rien en swing désolé

  6. #6
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 851
    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 851
    Points : 22 863
    Points
    22 863
    Billets dans le blog
    51
    Par défaut
    C'est simple : tu mets tout dans maCarte mais jamais tu ne mets ce panel dans ta frame via :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    add(maCarte, BorderLayout.CENTER);
    ou :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setContentPane(maCarte);
    Il est donc normal que rien n'apparaisse sur l'ecran.

    Ceci devrait mieux fonctionner :

    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
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
     
    package test;
     
    import java.awt.*;
    import java.awt.geom.*;
    import java.awt.image.*;
     
    import java.io.*;
     
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.event.*;
     
    import javax.imageio.*;
     
    public class Map extends JFrame {
     
      //Variables d'instance
      protected MapPane mapPane;
      protected BufferedImage image;
      protected JSlider curseur = new JSlider(JSlider.VERTICAL, 1, 3, 1);
     
      /** Creates a new instance.
       * @exception Exception In case of errors.
       */
      public Map() throws Exception {
        //Initialisation du JPanel
        // Lecture de l'image par ImageIO en mode synchrone.
        image = ImageIO.read(new File("test.jpg"));
        //Ajout du contenu
        mapPane = new MapPane(image);
        //mapPane.setBorder(new TitledBorder("Map"));
        curseur.setMajorTickSpacing(1);
        curseur.setMinorTickSpacing(1);
        curseur.setPaintLabels(true);
        curseur.setPaintTicks(true);
        curseur.setSnapToTicks(true);
        curseur.addChangeListener(new ChangeListener() {
          /** {@inheritDoc}
           */
          public void stateChanged(ChangeEvent e) {
            JSlider curseur = (JSlider) e.getSource();
            int scale = curseur.getValue();
            mapPane.setScale(scale);
            repaint();
          }
        });
        setLayout(new BorderLayout());
        add(new JScrollPane(mapPane), BorderLayout.CENTER);
        add(curseur, BorderLayout.EAST);
      }
     
      /** Self-test main.
       * @param args Arguments from the command line.
       */
      public static void main(String ...args) {
        try {
          Map map = new Map();
          map.setSize(400, 400);
          map.setTitle("Test");
          map.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          map.setVisible(true);
        }
        catch (Exception e) {
          e.printStackTrace();
        }
      }
     
      /** Displays the map.
       */
      private static class MapPane extends JPanel {
        private BufferedImage image;
        private int scale = 1;
     
        /** Creates a new instance with given image.
         * @param image The initial image.
         */
        public MapPane(BufferedImage image) {
          super();
          setImage(image);
        }
     
        /** Recalculer correctement la taille du panel.
         */
        private void recalculateAndResetSize() {
          int width = 0;
          int height = 0;
          // Tenir compte de la bordure optionnelle du panel.
          Insets insets = getInsets();
          width += insets.left + insets.right;
          height += insets.top + insets.bottom;
          // Tenir compte de la taille de l'image.
          if (image != null) {
            width += image.getWidth() * scale;
            height += image.getHeight() * scale;
          }
          Dimension size = new Dimension(width, height);
          setSize(size);
          setMinimumSize(size);
          setPreferredSize(size);
        }
     
        //////////////////////
        // Getters/Setters. //
        //////////////////////
     
        /** Sets the background image.
         * @param image The new image.
         * @see #getImage
         */
        public void setImage(BufferedImage image) {
          this.image = image;
          recalculateAndResetSize();
          repaint();
        }
     
        /** Gets the background image.
         * @return A <code>BufferedImage</code> instance.
         * @see #setImage
         */
        public BufferedImage getImage() {
          return image;
        }
     
        /** Sets the scale factor to given value.
         * @param value The new value.
         * @see #getScale
         */
        public void setScale(int value) {
          this.scale = value;
          recalculateAndResetSize();
          repaint();
        }
     
        /** Gets the scale factor.
         * @return An int.
         * @see #setScale
         */
        public int getScale() {
          return scale;
        }
     
        /** {@inheritDoc}
         */
        @Override public void setBorder(Border border) {
          super.setBorder(border);
          recalculateAndResetSize();
        }
     
        ////////////////
        // Rendering. //
        ////////////////
     
        /** {@inheritDoc}
         */
        @Override protected void paintComponent(Graphics graphics) {
          super.paintComponent(graphics);
          Graphics2D g2d = (Graphics2D) graphics;
          if (image != null) {
            Insets insets = getInsets();
            Dimension size = getSize();
            int panelWidth = size.width - (insets.left + insets.right);
            int panelHeight = size.height - (insets.top + insets.bottom);
            int scaledImageWidth = image.getWidth() * scale;
            int scaledImageHeight = image.getHeight() * scale;
            int x = (panelWidth - scaledImageWidth) / 2;
            int y = (panelHeight - scaledImageHeight) / 2;
            // Pour permettre au bord optionnel d'etre dessine.
            g2d.translate(insets.left, insets.top);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
            g2d.drawImage(image, x, y, scaledImageWidth, scaledImageHeight, null);
            // Retour a l'origine du repere.
            g2d.translate( -insets.left, -insets.top);
          }
        }
      }
    }
    Parmis les modification :
    - ajout d'un main permettant de tester.
    - suppression de maCarte ; les composants sont en effet directement integres a la frame.
    - ajout d'un scroll pane sur le panel contenant l'image.
    - le curseur de la slider colle aux valeur via curseur.setSnapToTicks(true)
    - utilisation de ImageIO pour charger l'image. En effet Toolkit charge l'image de maniere asynchrone et donc celle-ci peut ne pas etre completement chargee en memoire lors de l'affichage ou lorsqu'on a besoin de ses dimensions.
    - suppression des methodes de generation d'une nouvelle image. L'image est affichee dynamiquement zoomee via la methode d'affichage appropriee.
    - prise en compte de la bordure optionnelle sur le panel affichant l'image dans les calculs.
    - l'image s'affiche centree sur le panel. Les calculs des coordonnee d'affichage x et y sont necessaires car le panel etant dans un scroll pane il peut avoir une taille superieure a celle que nous lui avons donne.

  7. #7
    HiT
    HiT est déconnecté
    Débutant
    Inscrit en
    Juillet 2004
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 74
    Points : 20
    Points
    20
    Par défaut
    ca marche merciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
    me reste plus qu'à mettre dans un panel de taille fixe et à mettre un drag and drop sur la carte pour se déplacer et mon projet sera bien avancé
    merci encore

  8. #8
    Membre régulier Avatar de Kevin12
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 122
    Points : 74
    Points
    74
    Par défaut
    - utilisation de ImageIO pour charger l'image. En effet Toolkit charge l'image de maniere asynchrone et donc celle-ci peut ne pas etre completement chargee en memoire lors de l'affichage ou lorsqu'on a besoin de ses dimensions.
    J'utilise toolkit, mais mon problème est de récupérer la largeur de mon image.
    génére le message d'erreur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    getWidth() cannot be applied to ()

  9. #9
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 851
    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 851
    Points : 22 863
    Points
    22 863
    Billets dans le blog
    51
    Par défaut
    Geez ca c'est du deterrage...

    Les methodes getWidth() et getHeight() font partie de BufferedImage... tandis que Image ne contient que getWidth(ImageObserver obs) et getHeight(ImageObserver obs) sachant que dans le cas d'une image deja completement chargee, il est courant de passer null en parametre.

    Un petit tour dans la javadoc s'impose, de meme qu'il faudra apprendre a correctement interpreter les erreurs du compilateur ou de l'IDE.

Discussions similaires

  1. Zoom sur image
    Par gege59 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 17/08/2009, 21h13
  2. [VB.NET2.0][Debutant]zoom sur image
    Par Emcy dans le forum Windows Forms
    Réponses: 2
    Dernier message: 15/06/2006, 15h03
  3. [html][css] 3 lv de zoom sur image sous IE et firefoxe
    Par avogadro dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 10/04/2006, 22h37
  4. [FLASH 8] Zoom sur image
    Par kmomille dans le forum Flash
    Réponses: 6
    Dernier message: 09/03/2006, 14h17
  5. zoom sur image de formulaire
    Par bourvil dans le forum VBA Access
    Réponses: 2
    Dernier message: 01/10/2003, 09h25

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