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

AWT/Swing Java Discussion :

redimensionner une image assez grosse


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2006
    Messages : 48
    Par défaut redimensionner une image assez grosse
    Salut!

    J'ai fait un petit programme dans lequel je dois redimensionner une photo choisie dans le système de fichier. Ma méthode pour redimensionner l'image ressemble à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public Image redimensionnerImage(Image im){
    		return im.getScaledInstance(80,120,Image.SCALE_DEFAULT);
    	}
    Mais j'ai de très mauvaises performances, en particulier sur les grosses photos (en terme de nombre de pixels plus que de taille sur le disque apparemment), le redimensionnement prend facilement une petite dizaine de secondes sur des photos de coté 500 ou 600 pixels environs, et pour les photos qui vont chercher dans les plus 1000*1000 pixels, ca travaille carrément un moment avant de me sortir cette erreur :

    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
    Exception during event dispatch:
    java.lang.ArrayIndexOutOfBoundsException: 9600
       at gnu.java.awt.peer.gtk.GtkImageConsumer.setPixels(lib-gnu-java-awt-peer-gtk.so.7)
       at java.awt.image.ReplicateScaleFilter.setPixels(libgcj.so.7)
       at java.awt.image.BufferedImage$1.startProduction(libgcj.so.7)
       at java.awt.image.FilteredImageSource.startProduction(libgcj.so.7)
       at gnu.java.awt.peer.gtk.GtkImage.<init>(lib-gnu-java-awt-peer-gtk.so.7)
       at gnu.java.awt.peer.gtk.GtkToolkit.createImage(lib-gnu-java-awt-peer-gtk.so.7)
       at java.awt.Image.getScaledInstance(libgcj.so.7)
       at carteMakerFrame.redimensionnerImage(carteMaker.java:484)
       at carteMakerFrame.actionPerformed(carteMaker.java:310)
       at javax.swing.AbstractButton.fireActionPerformed(libgcj.so.7)
       at javax.swing.AbstractButton$1.actionPerformed(libgcj.so.7)
       at javax.swing.DefaultButtonModel.fireActionPerformed(libgcj.so.7)
       at javax.swing.DefaultButtonModel.setPressed(libgcj.so.7)
       at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(libgcj.so.7)
       at java.awt.Component.processMouseEvent(libgcj.so.7)
       at java.awt.Component.processEvent(libgcj.so.7)
       at java.awt.Container.processEvent(libgcj.so.7)
       at java.awt.Component.dispatchEventImpl(libgcj.so.7)
       at java.awt.Container.dispatchEventImpl(libgcj.so.7)
       at java.awt.Component.dispatchEvent(libgcj.so.7)
       at java.awt.LightweightDispatcher.handleEvent(libgcj.so.7)
       at java.awt.Container.dispatchEventImpl(libgcj.so.7)
       at java.awt.Window.dispatchEventImpl(libgcj.so.7)
       at java.awt.Component.dispatchEvent(libgcj.so.7)
       at java.awt.EventQueue.dispatchEvent(libgcj.so.7)
       at java.awt.EventDispatchThread.run(libgcj.so.7)
    Est-ce que qqn connait une méthode plus légère pour redimensionner les images ?
    Merci...

  2. #2
    Membre chevronné
    Avatar de Orian
    Inscrit en
    Août 2006
    Messages
    372
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations forums :
    Inscription : Août 2006
    Messages : 372

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

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Mouaip mieux vaut ne pas uttiliser le getScaledInstance qui est 100% software et bouffe paquet de mémoire

    utilise quelque chose dans ce style plutôt:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Image imageAReduire = ...;
    // ...
    BufferedImage image = new BufferedImage(BufferedImage.TYPE_INT_ARGB, imageAReduire.getWidth(null), imageAReduire.getHeight(null));
    Graphics2D g2 = image.createGraphics();
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g2.drawImage(imageAReduire, 0, 0, nouvelleLargeur, nouvelleHauteur, null);
    g2.dispose();
    imageAReduire = image;
    Ensuite tu n'utilises pas la JVM standard mais celle de GNU Classpath (GCJ) qui peut causer des problèmes à ce niveau là...

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2006
    Messages : 48
    Par défaut
    merci sinok jvais essayer ca jvous redis

    la méthode de la faq avec getScaledInstance prend autant de temps, mais ne fonctionne pas et me donne un joli "Aborted".

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

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Je répète le post précédent avec un peu plus de précisions: c'est dû au fait que getScaledInstance est très couteux au niveau ressources (il n'utilise pas la carte vidéo pour faire les manips) et que tu utilises une JVM pas fontionnelle à 100% même si elle n'est est pas loin.

    D'ailleurs vu que tu fais du swing tu risques de tomber rapidement sur des problèmes car swing marche realivement mal avec Gcj, même si ça s'est amélioré dernièrement avec la mise en place d'une correspondance en les Graphics/Graphics2D et pango et cairo.

  6. #6
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par ratakses
    la méthode de la faq avec getScaledInstance prend autant de temps, mais ne fonctionne pas et me donne un joli "Aborted".
    La méthode de la FAQ est mauvaise, utilise celle de sinok

  7. #7
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Il y a mieux encore. La méthode ci-dessous fournit un résultat plus joli que la méthode simple proposée par sinok. Le temps d'exécution est comparable (sur mon dernier test, cela prenait quelques millisecondes de plus que la méthode simple : 15ms au lieu de ~12/10ms sur une image en 640x480 redimensionnée à 120 pixels de large).

    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
     
       public static BufferedImage createThumbnail(BufferedImage image, int requestedThumbSize) {
            float ratio = (float) image.getWidth() / (float) image.getHeight();
            int width = image.getWidth();
            boolean divide = requestedThumbSize < width;
            BufferedImage thumb = image;
     
            do {
                if (divide) {
                    width /= 2;
                    if (width < requestedThumbSize) {
                        width = requestedThumbSize;
                    }
                } else {
                    width *= 2;
                    if (width > requestedThumbSize) {
                        width = requestedThumbSize;
                    }
                }
     
                BufferedImage temp = new BufferedImage(width, (int) (width / ratio),
                                                       image.getType());
                Graphics2D g2 = temp.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null);
                g2.dispose();
     
                thumb = temp;
            } while (width != requestedThumbSize);
     
            return thumb;
        }

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

Discussions similaires

  1. [VB.NET] Redimensionner une image dans un PictureBox
    Par Monster77 dans le forum Windows Forms
    Réponses: 6
    Dernier message: 05/04/2007, 18h24
  2. [32 bits] Redimensionner une image JPEG/GIF/PNG...
    Par CR_Gio dans le forum x86 32-bits / 64-bits
    Réponses: 2
    Dernier message: 04/10/2005, 00h57
  3. Redimensionner une image...
    Par RhaZieL dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 22/07/2005, 09h30
  4. [VB.NET] Redimensionner une image proportionnelement
    Par Monster77 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 19/10/2004, 12h10
  5. [MX2004] redimensionner une image lors du chargement
    Par ouinouin dans le forum Flash
    Réponses: 8
    Dernier message: 18/02/2004, 18h32

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