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

Graphisme Java Discussion :

[Graphics2D][formattedTextField] pour rogner une image


Sujet :

Graphisme Java

  1. #1
    Membre habitué
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 379
    Points : 129
    Points
    129
    Par défaut [Graphics2D][formattedTextField] pour rogner une image
    Bonjour à tous,

    j'ai développer une application qui permet d'analyser des images. Mais l'analyse ne peut marcher que s'il n'y a pas de bords noir en bas de l'image.

    J'aimerais donc rajouter à mon application la possibilité de rogner une image. En faisant quelques recherches sur le forum, j'ai trouvé ce post qui parle de la méthode getSubImage pour rogner une bufferedImage, et celui-ci qui donne des idées générales pour sélectionner une zone dans un dessin.

    En fait, je ne sais pas trop dans quelle direction partir.
    J'hésite entre :
    • faire apparaitre une petite fenetre (cf. image jointe) dans laquelle on met le nombre de pixels qu'on veut rogner de chaque côtés (un peu comme la fonction de rognage proposée dans Word)
    • agir directement sur l'image en sélectionnant une zone de l'image avec la souris, puis rogner tout ce qui est à l'extérieur du rectangle ainsi obtenu (même fonctionnement que Gimp)


    J'ai commencé à développer la première solution : voici le code de la petite fenêtre de rognage telle quelle est actuellement :
    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
    180
    181
    182
    183
    184
    /**
     * Projet : LAM
     * Paquetage : fr.statlife.LAM.IHM
     * Fichier : ActionRogner.java
     *
     * @author Mathilde Pellerin
     * @date 3 sept. 2010
     */
    package fr.statlife.LAM.IHM;
     
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics2D;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.image.BufferedImage;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.text.NumberFormat;
     
    import javax.swing.AbstractAction;
    import javax.swing.JFormattedTextField;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
     
    /**
     * 
     * @author Mathilde Pellerin
     */
    @SuppressWarnings("serial")
    public class ActionRogner extends AbstractAction implements PropertyChangeListener
    {
    	private FenetreLAM fenetre;
    	private JPanel panneau;
    	private PanneauMammo panneauApercu;
    	private NumberFormat formatValeur;
    	private BufferedImage mammo;
     
    	private JFormattedTextField	fieldHaut;
    	private JFormattedTextField	fieldBas;
    	private JFormattedTextField	fieldGauche;
    	private JFormattedTextField	fieldDroite;
     
    	private int nbPixelHaut;
    	private int nbPixelBas;
    	private int nbPixelGauche;
    	private int nbPixelDroite;
    	private Graphics2D	g2d;
     
    	public ActionRogner(final FenetreLAM fenetre, String texte)
    	{
    		super(texte);
     
    		this.fenetre = fenetre;
     
    		formatValeur = NumberFormat.getNumberInstance();
    		formatValeur.setMaximumIntegerDigits(3);
    		this.panneau = construirePanneau();
    	}
     
    	/* (non-Javadoc)
    	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
    	 */
    	@Override
    	public void actionPerformed(ActionEvent e)
    	{
    		//(Re)mise a zero des champs
    		fieldHaut.setValue(0);
    		fieldBas.setValue(0);
    		fieldGauche.setValue(0);
    		fieldDroite.setValue(0);
     
    		mammo = fenetre.getPanneauMammoNative().getImg();
    		panneauApercu.setImg(mammo);
     
    		JOptionPane.showConfirmDialog(
    			this.fenetre,
    			new Object[]{
    				this.panneau
    			},
    			FenetreLAM.messages.getString("boutonRogner"),
    			JOptionPane.OK_CANCEL_OPTION,
    			JOptionPane.PLAIN_MESSAGE
    		);
    	}
     
    	private JPanel construirePanneau()
    	{
    		//Construction du panneau principal
    		JPanel panneau = new JPanel(new GridLayout(1, 3));
    		panneau.setPreferredSize(new Dimension(350, 150));
     
    		//Construction du panneau qui contient le reglage des dimensions
    		JPanel panneauDimension = new JPanel(new GridLayout(4, 2));
    		JLabel labelHaut = new JLabel(FenetreLAM.messages.getString("labelRognageHaut"));
    		JLabel labelBas = new JLabel(FenetreLAM.messages.getString("labelRognageBas"));
    		JLabel labelGauche = new JLabel(FenetreLAM.messages.getString("labelRognageGauche"));
    		JLabel labelDroite = new JLabel(FenetreLAM.messages.getString("labelRognageDroite"));
    		fieldHaut = new JFormattedTextField(formatValeur);
    		fieldHaut.addPropertyChangeListener("value", this);
     
    		fieldBas = new JFormattedTextField(formatValeur);
    		fieldBas.addPropertyChangeListener("value", this);
     
    		fieldGauche = new JFormattedTextField(formatValeur);
    		fieldGauche.addPropertyChangeListener("value", this);
     
    		fieldDroite = new JFormattedTextField(formatValeur);
    		fieldDroite.addPropertyChangeListener("value", this);
     
    		panneauDimension.add(labelHaut);
    		panneauDimension.add(fieldHaut);
    		panneauDimension.add(new JLabel());
    		panneauDimension.add(labelBas);
    		panneauDimension.add(fieldBas);
    		panneauDimension.add(new JLabel());
    		panneauDimension.add(labelGauche);
    		panneauDimension.add(fieldGauche);
    		panneauDimension.add(new JLabel());
    		panneauDimension.add(labelDroite);
    		panneauDimension.add(fieldDroite);
    		panneauDimension.add(new JLabel());
     
    		//Construction du panneau qui contient l'apercu miniature
    		panneauApercu = new PanneauMammo();
     
    		panneau.add(panneauDimension);
    		panneau.add(panneauApercu);
    		return panneau;
    	}
     
    	/* (non-Javadoc)
    	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
    	 */
    	@Override
    	public void propertyChange(PropertyChangeEvent evt)
    	{
    		if(mammo != null)
    		{
    			Object source = evt.getSource();
     
    			g2d = mammo.createGraphics(); // on récupère le contexte graphique de la BufferedImage   
    	    	g2d.setColor( Color.red ); // on met l'état de couleur rouge à la BufferedImage
     
    		    if (source == fieldHaut) 
    		    {
    		    	nbPixelHaut = ((Number)fieldHaut.getValue()).intValue();
     
    		    	//on trace la ligne en haut qui delimite la zone a rogner
    		    	g2d.fillRect(0, nbPixelHaut, mammo.getWidth(), 2);
    		    	g2d.dispose(); //on libère la mémoire utilisée pour le contexte graphique
    		    	panneauApercu.setImg(mammo);
    		    }
    		    else if(source == fieldBas) 
    		    {
    		    	nbPixelBas = ((Number)fieldBas.getValue()).intValue();
     
    		    	//on trace la ligne en bas qui delimite la zone a rogner
    		    	g2d.fillRect(0, mammo.getHeight() - nbPixelBas, mammo.getWidth(), 2);
    		    	g2d.dispose(); //on libère la mémoire utilisée pour le contexte graphique
    		    	panneauApercu.setImg(mammo);
    		    }
    		    else if(source == fieldGauche) 
    		    {
    		    	nbPixelGauche = ((Number)fieldGauche.getValue()).intValue();
     
    		    	//on trace la ligne a gauche qui delimite la zone a rogner
    		    	g2d.fillRect(nbPixelGauche, 0, 2, mammo.getHeight());
    		    	g2d.dispose(); //on libère la mémoire utilisée pour le contexte graphique
    		    	panneauApercu.setImg(mammo);
    		    }
    		    else if(source == fieldDroite) 
    		    {
    		    	nbPixelDroite = ((Number)fieldDroite.getValue()).intValue();
     
    		    	//on trace la ligne a droite qui delimite la zone a rogner
    		    	g2d.fillRect(mammo.getWidth() - nbPixelDroite, 0, 2, mammo.getHeight());
    		    	g2d.dispose(); //on libère la mémoire utilisée pour le contexte graphique
    		    	panneauApercu.setImg(mammo);
    		    }
    		}
    	}
    }
    le problème avec ce code, c'est que la ligne rouge que je trace pour montrer à l'utilisateur où sera rognée l'image ne disparait jamais. Donc si on teste plusieurs valeurs, j'aurais plusieurs lignes rouges dessinées sur l'image... Je ne sais pas comment effacer une ligne rouge sans effacer l'image qu'il y a en dessous aussi.
    Est-ce possible??

    Autre problème, j'ai lu dans le How to use formattedTextFiled, que la valeur la méthode commitEdit est appelée à chaque fois que le focus du formattedTextField est perdu, ce qui permet en utilisant un listener, de savoir quand la valeur a changé, et donc dans mon cas, quand tracer une nouvelle ligne rouge.
    Le problème c'est que ça marche pas à chaque fois sans que je comprenne pourquoi...
    Donc si quelqu'un peut m'éclairer sur ce qu'il se passe réellement, ça serait chouette

    PS : je vous mets aussi le code de la classe PanneauMammo que j'utilise pour afficher mes images, au cas où ça expliquerait des choses...
    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
    /**
     * Projet : LAM
     * Paquetage : fr.statlife.LAM.IHM
     * Fichier : PanneauMammo.java
     *
     * @author Mathilde Pellerin
     * @date 11 mai 2010
     */
    package fr.statlife.LAM.IHM;
     
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
     
    import javax.imageio.ImageIO;
    import javax.swing.BorderFactory;
    import javax.swing.JPanel;
     
    import fr.statlife.LAM.Image;
     
    /**
     * 
     * @author Mathilde Pellerin
     */
    @SuppressWarnings("serial")
    public class PanneauMammo extends JPanel
    {
    	private BufferedImage img;
    	private BufferedImage fondBlanc;
     
    	public PanneauMammo()
    	{
    		super();
    		try
    		{	
    			this.fondBlanc = ImageIO.read(getClass().getClassLoader().getResource(
    					"pointBlanc.gif"));
    		} 
    		catch (IOException e)
    		{
    			e.printStackTrace();
    		}
     
    		this.img = fondBlanc;
    		this.setBorder(BorderFactory.createLineBorder(Color.black));
    	}
     
    	public PanneauMammo(Image img)
    	{
    		super();
    		this.img = img.getImage();
    	}
     
     
    	/**
             * permet de dessiner la mammo dans un panneau (JPanel)
             */
    	public void paintComponent(Graphics g)  
    	{
    		g.drawImage(img, 1, 1, this.getWidth(), this.getHeight(), null);
    	}
     
     
    	/**
             * ACCESSEURS
             */
     
    	public BufferedImage getImg()
    	{
    		return img;
    	}
     
    	public void setImg(BufferedImage image)
    	{
    		if(image == null)
    			this.img = fondBlanc;
    		else
    			this.img = image;
     
    		repaint();
    	}
    }
    Images attachées Images attachées  

  2. #2
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    En fait ta ligne rouge ne devrait pas être dessinée sur l'image, mais sur le composant servant à afficher l'image. EN effets ils ne servent que de repère visuel, rien d'autre vu que le cropping ne se fait absolument pas par rapport aux lignes rouges mais par rapport aux valeurs entrées dans les textfields...

    De fait il te suffit d'ajouter le concept des lignes dans la classe PanneauMammo et de mettre à disposition des méthodes pour modifier leur emplacements. Méthodes qui seront appelée en cas de changement des valeurs entrées dans le JFormattedTextFields.

    Comme ça plus le moindre problème

  3. #3
    Membre habitué
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 379
    Points : 129
    Points
    129
    Par défaut
    pas bête du tout !!!

    je vais faire ça comme ça

    merci beaucoup pour l'idée

    je reviendrais mettre un résolu quand ça sera implémenté, pour le cas où j'y arrive pas du premier coup (même si a vu de nez ça semble pas bien compliqué à mettre en place...)

  4. #4
    Membre habitué
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 379
    Points : 129
    Points
    129
    Par défaut
    bon bah tu vois, j'ai bien fait de pas mettre résolu direct

    dans la classe PanneauMammo, j'ai ajouté la méthode 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
    	/**
             * tracerLigneHorizontale : trace une ligne horizontale sur le panneau
             * @param y : coordonnee y de la ligne a tracer
             */
    	public void tracerLigneHorizontale(int y)
    	{
    		Graphics g = this.getGraphics();
     
    		//Tracage en rouge d'une ligne horizontale
        	g.setColor(Color.red);
        	g.fillRect(0, y, img.getWidth(), 2);
     
        	g.dispose(); //on libère la mémoire utilisée pour le contexte graphique
        	repaint();
    	}
    elle ne marche que si je mets
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Graphics2D g = img.createGraphics();
    à la place de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Graphics g = this.getGraphics();
    et bien évidemment, si je fais un img.createGraphics, je me retrouve avec le même problème qu'avant.
    Je comprends pas pourquoi avec le this.getGraphics() ça ne marche pas, même si je le caste en Graphics2D...
    pourtant this est un JPanel, je vois pas où est le problème...

    d'autant moins que j'ai testé en mettant le code pour tracer la ligne directement dans la méthode paintComponent, et que là ça marche, la ligne est tracée au moment de l'affichage...
    Bref, il y a visiblement une subtilité qui m'échappe (effet vendredi soir peut être )...

  5. #5
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Il ne faut jamais utiliser getGraphics pour dessiner sur un composant.

    Il faut que les opérations de dessin s'effectuent dans la méthode paintComponent. Dans ton cas juste après le drawImage.

    En effet, les Graphis sont des objets à durée de vie assez courte, et les graphics obtenus via un getGraphics seront invalidés et inutiles de fait dès le prochain repaint.

    Autre chose, il ne fait jamais appeler de dispose sur les graphics fournit en paramètre. On ne fait de dispose que sur les graphics fournits par un BufferedImage.createGraphics/getGraphics ou un Graphics.createGraphics.

    Donc à toi de faire en sorte que ça marche en employant le paintComponent.

  6. #6
    Membre habitué
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 379
    Points : 129
    Points
    129
    Par défaut
    ok, je comprends mieux.

    merci beaucoup pour ces explications, je devrais réussir à m'en sortir du coup

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

Discussions similaires

  1. Macro pour rogner une image
    Par malabarbe dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 10/08/2007, 22h57
  2. Réponses: 13
    Dernier message: 23/12/2004, 18h01
  3. recadrer (rogner) une image
    Par prodi_64 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 19/10/2004, 11h57
  4. Comment faire pour afficher une image ds une dbgrid
    Par totomaze dans le forum Bases de données
    Réponses: 2
    Dernier message: 16/10/2004, 15h31
  5. Mkisofs - problème pour créer une image
    Par tomnie dans le forum Applications et environnements graphiques
    Réponses: 4
    Dernier message: 04/08/2004, 11h44

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