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 :

: Redimensionnement d'image JPEG


Sujet :

2D Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 45
    Par défaut [Resolu] : Redimensionnement d'image JPEG
    Voila,

    j'ai un programme qui redimensionne des images JPEG de tailles quelconques.
    Cependant certaines photos qui ne sont pas forcement excessivement grosses font planter la JVM avec un "java.lang.OutOfMemoryError".

    Voici le programme

    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
    public boolean resize(int i, String s, String s1)
        {
     
            float af[] = {
                0.3333333F, 0.2F, 0.2F, 0.3333333F
            };
            boolean flag = false;
            boolean flag1 = false;
            boolean flag2 = false;
            Object obj = null;
            Object obj1 = null;
            Object obj2 = null;
            File file = new File(s);
            File file1 = new File(s1);
     
            BufferedImage bufferedimage = ImageIO.read(file);
     
    //CA PLANTE TOUJOURS A CET ENDROIT
     
            Raster raster = bufferedimage.getData();
     
            double d = bufferedimage.getWidth();
            double d1 = bufferedimage.getHeight();
            double d2 = i;
            double d3 = d2 / d1;
     
            if(d > d1)
            {
                d3 = d2 / d;
            }
     
            if(d3 > 1.0D)
            {
                d3 = 1.0D;
            }
            int j = (int)(d * d3);
            int k = (int)(d1 * d3);
     
            BufferedImage bufferedimage1 = new BufferedImage(j, k, bufferedimage.getType());
     
            WritableRaster writableraster = bufferedimage1.getRaster();
     
            int ai[] = new int[4];
            int ai1[] = new int[4];
            int l = (int)d / j;
            int i1 = (int)d1 / k;
     
            for(int j1 = 0; j1 < j; j1++)
            {
                for(int k1 = 0; k1 < k; k1++)
                {
                    ai[0] = 0;
                    ai[1] = 0;
                    ai[2] = 0;
                    ai[3] = 0;
                    for(int l1 = 0; l1 < l; l1++)
                    {
                        for(int i2 = 0; i2 < i1; i2++)
                        {
                            raster.getPixel(j1 * l + l1, k1 * i1 + i2, ai1);
                            ai[0] += ai1[0];
                            ai[1] += ai1[1];
                            ai[2] += ai1[2];
                            ai[3] += ai1[3];
                        }
     
                    }
     
                    ai[0] /= i1 * l;
                    ai[1] /= i1 * l;
                    ai[2] /= i1 * l;
                    ai[3] /= i1 * l;
                    writableraster.setPixel(j1, k1, ai);
                }
     
            }
     
            ImageIO.write(bufferedimage1, "JPEG", file1);
     
            return true;
            IOException ioexception;
            ioexception;
     
            return false;
        }
    J'ai mis l'endroit ou ca plante toujours, c'est à dire au moment du

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Raster raster = bufferedimage.getData();
    J'utilise des photos provenant d'appareil numerique, elles font generalement en 5 et 10Mo et c'est pas forcement les plus grosses qui font planter la JVM.

    Ce que j'aimerai savoir c'est si quelqu'un à une idée du pourquoi ca pourrait planter et si vous voyez une autre maniere de proceder à la chose

    Merci de votre aide[/b]

  2. #2
    Membre émérite
    Avatar de efficks
    Inscrit en
    Septembre 2005
    Messages
    712
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 712
    Par défaut
    Ferme tu tous tes liens vers les fichiers? ou restent-ils ouvert après traitement?

  3. #3
    Membre chevronné Avatar de let_me_in
    Inscrit en
    Mai 2005
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 441
    Par défaut
    et si tu fesais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Raster raster=bufferedimage.createRaster(bufferedimage.getSampleModel() , bufferedimage.getDataBuffer() , Point location);

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 45
    Par défaut
    C'est à dire?

    Je ne fais que ca...

    J'instancie mon objet Jpeg et ensuite j'effectue mon jpeg.resize (...) et c'est tout...

    donc je pense que non.

  5. #5
    Membre émérite
    Avatar de efficks
    Inscrit en
    Septembre 2005
    Messages
    712
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 712
    Par défaut
    Je ne sais pas s'il faut fermer un buffer mais moi j'essairait la méthode :
    ImageIO.close() si elle existe.

  6. #6
    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
    Encore mieux : pourquoi tu n'utilises pas les fonctions de redimensionnement fournies dans le JDK ?

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 45
    Par défaut
    Citation Envoyé par Gfx
    Encore mieux : pourquoi tu n'utilises pas les fonctions de redimensionnement fournies dans le JDK ?
    Y en a ???
    Tu peux m'indiquer dans quelle classe stp?

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 45
    Par défaut
    Citation Envoyé par let_me_in
    et si tu fesais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Raster raster=bufferedimage.createRaster(bufferedimage.getSampleModel() , bufferedimage.getDataBuffer() , Point location);
    Mais la methode getDataBuffer n'existe pas dans la classe BufferedImage ! ? ??

  9. #9
    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
    drizztoli, voila comment on redimensionne une image :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    BufferedImage source = ...;
    GraphicsConfiguration configuration = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
            BufferedImage compatibleImage = configuration.createCompatibleImage(nouvelleLargeur, nouvelleHauteur);
    Graphics g = petit.getGraphics();
    g.drawImage(source, 0, 0, nouvelleLargeur, nouvelleHauteur);
    g.dispose();
    A la place de la 2e et de la 3e ligne tu peux ecrire cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    BufferedImage petit = new BufferedImage(nouvelleLargeur, nouvelleHauteur, source.getType());
    Mais dans le cas d'un JPEG, cela n'ira pas aussi vite. La premiere methode s'assure que l'operation est realisee par la carte graphique ce qui donne d'excellentes performances.

    Si tu avais regarde attentivement la documentation de la classe BufferedImage, tu aurais decouvert la methode getScaledInstance() qui renvoie une version redimensionnee de l'image... SURTOUT NE L'UTILISE PAS. Elle est tres tres lente (comme ton code en fait).

    Enfin, si tu veux des images redimensionnees de qualite tout en ayant de bonnes performances utilise ca :

    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
     
        public static BufferedImage createThumbnail(BufferedImage image, int requestedThumbSize) {
            float ratio = (float) image.getWidth() / (float) image.getHeight();
            int width = image.getWidth();
            BufferedImage thumb = image;
     
            do {
                width /= 2;
                if (width < requestedThumbSize) {
                    width = requestedThumbSize;
                }
     
                BufferedImage temp = new BufferedImage(width, (int) (width / ratio), BufferedImage.TYPE_INT_ARGB);
                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;
        }
    Cela ne marchera que pour reduire la taille de l'image. Le resultat est plus joli que la premiere methode et presque aussi rapide (a peu pres 15 millisecondes pour redimensionner une image en 800x600 sur mon dernier test).

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 45
    Par défaut
    Merci de ton aide, je vais regarder ca attentivement!

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 45
    Par défaut
    Verdict

    J'ai fait un test sur une image de 10Mo qui a pour taille 3800 * 2500.

    Je fais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    createThumbnail (l'image buffered, 500)
    -> au moment du :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null);
    et bien le programme bloque apparemment, il ne passe pas a l'etape suivante et java me prend 99 % de mes ressources...


    EDIT : bon ca a ete long (je dois avoir une carte graphique de m.... au bureau), mais ca a fonctionné... Cependant, j'ai perdu vachement de qualite sur l'image et les couleurs... ca peut etre du a quoi ?

  12. #12
    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
    Remplace ARGB par RGB.

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 45
    Par défaut
    Merci c'est parfait!!!

    Encore merci pour tout!

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

Discussions similaires

  1. Redimensionner une image jpeg
    Par zerimbak dans le forum GTK+ avec C & C++
    Réponses: 4
    Dernier message: 06/01/2011, 19h43
  2. [ImageMagick] Redimensionner une image JPEG PNG GIF
    Par Stouille89 dans le forum Bibliothèques et frameworks
    Réponses: 11
    Dernier message: 25/08/2007, 21h10
  3. Redimensionner une image JPEG
    Par BlackLynX dans le forum C++
    Réponses: 2
    Dernier message: 26/02/2007, 21h23
  4. Redimensionner une image jpeg
    Par Futixu dans le forum C++Builder
    Réponses: 2
    Dernier message: 13/12/2006, 14h42
  5. [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

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