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

Java Discussion :

Comment envoyer plusieurs images a un serveur?


Sujet :

Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 16
    Points : 10
    Points
    10
    Par défaut Comment envoyer plusieurs images a un serveur?
    Bonjour,

    j'ai des image a envoyer un serveur (output).

    Mon problème se situe au moment ou j'ai un "java heap space" mais je ne dois pas augmenter la taille de la jvm. Pour être plus précis il ne plante pas à la première image, pourtant je fais un flush, un close et j'envoi 1 seule image en même temps... je ne sais pas pourquoi il garde en mémoire (je crois que c'est des int[] qui stocke les images) jusqu'au javaheapspace.

    J'ai essayer d'envoyer des ImagesIcon, des Images en buffer(byte[]). Dans le second cas j'ai un "java heap space" pendant la transformation avant mon envoi.

    Y'a t-il d'autres solution pour que j'envoi des images ou si je peux faire autre chose pour vider les images de la mémoire? est-ce possible?

    Merci.

    Cédric

    ps:s'il faut d'autres info...

  2. #2
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Un peu de code est nécessaire pour voir ce qui est fait.
    Première remarque : il n'est pas nécessaire de mettre en mémoire l'image avant de l'envoyer, pourquoi ne pas écrire directement le flux vers le serveur ?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Voici mes 2 solutions de départ:

    1) Pour la première solution en dessous j'ai une "Imageicon" dans un object java (je ne sais pas s'il caut mieux pas stocker une "Image" plutot qu'une "Imageicon").
    Je veux ensuite l'envoyer vers le serveur.

    Plante parfois au "writeObject"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Code=
    ObjectOutputStream out=new ObjectOutputStream(conn.getOutputStream());
    out.writeObject(pj.getImageIcon());
    out.flush();
    out.close();
    2) Pour la 2ème solution je passe par un BufferedImage

    Plante parfois pendant la transformation du BufferedImage

    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
    Code=
    ObjectOutputStream dos = new ObjectOutputStream( conn.getOutputStream());
    //File file=new File
    ByteArrayOutputStream bas =
    new ByteArrayOutputStream();
    ImageIO.write(pj.getBufferedImage(), "jpeg", bas);
    byte[] buffer = bas.toByteArray();
    dos.writeInt(buffer.length);
    int readLength=0;
    while ((readLength < buffer.length)) {
            if(buffer.length>=readLength+2048)
            	dos.write(buffer, readLength, 2048);
            else
            	dos.write(buffer, readLength, buffer.length-readLength);
            dos.flush(); 
            readLength+=2048;
    }
    bas.flush();
    bas.close();
    dos.close();

  4. #4
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Tu ne devrais pas sérializer tes images. Considère l'image comme un simple fichier, et transmet le flux vers le serveur. Tu pourras ainsi transmettre des images de tailles aléatoires, même si elles font plusieurs giga-octets :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    InputStream input = ...ouverture fichier image...;
    OutputStream out = ...flux écriture vers serveur...;
    byte[] tab = new byte[ 1024 * 1024 ];
    int taille = 0;
     
    while( ( taille = input.read( tab ) ) > 0 )
    {
      out.write( tab, 0, taille );
    }
    ...
    fermeture des flux;
    }

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Merci, je vais essayer je pense que ta solution est la seule possible...

    Par contre j'ai oublier un gros détail, c'est que l'image que j'ai ne proviens pas d'un fichier mais soit d'un import, soit d'un scanner. Faut que je créer l'input (fiechier), en espérant que je n'ai pas le problème à ce niveau.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Désolé pour les questions mais je n'arrive pas trop a faire les transformations.

    Pouvez vous me dire comment faire pour avoir:

    - Image --> Fichier

    - InputStream du Fichier --> Image

    Merci

  7. #7
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Citation Envoyé par cedzed64 Voir le message
    - Image --> Fichier

    - InputStream du Fichier --> Image
    Mais ?!?!
    L'image, elle vient d'où ? Elle est sous quelle forme ? Elle est générée par quoi ?
    Dans le code du 3eme post, c'est quoi l'objet "pj" ?

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Désolé... j'ai pas bien expliquer.

    Mon image viens d'un scanner et d'une librairie qui importe l'image scanné, on arrive a avoir un objet Image. PJ contient les images + d'autres infos, les images je les ai mis sous la forme ImageIcon (je peut remettre en Image s'il faut).

    D'ici la je dois envoyer au serveur 1 ou plusieurs images. Je n'ai pas encore de fichier a ce moment.

    Sur le serveur je dois donner l'image pour quelle soit mise en base (après je fait aussi le coté serveur mais je dois avoir au final aussi un objet Image).

    Je t'ai mis en premier toutes mes recherches qui finissent par une erreur javaheapspace.

  9. #9
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 872
    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 872
    Points : 22 939
    Points
    22 939
    Billets dans le blog
    53
    Par défaut
    Si tes images sont en memoire, tu les converti en PNG grace a ImageIO en donnant un ByteArrayOutputStream en sortie, ce qui te permet de recuperer un byte[] a envoyer au serveur. A l'inverse sur le serveur, une fois le byte[] integralement recuperer, tu utilises un ByteArrayInputStream et ImageIO pour decoder l'image.

    Si vraiment tu dois etre plus conservateur pour l'usage de la memoire, stocke alors l'image (toujours en PNG) dans un fichier temporaire sur le disque avec ImageIO et lit-le et expedie-le en utilisant un buffer de la taille appropriee de maniere a ce que ce ne soit ni trop lent ni trop gourmand en memoire. Si tu as beaucoup d'images a gerer, tu ne peux donc pas te permettre d'avoir tout en memoire en meme temps et ca sera de toute maniere la meilleure solution.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Merci pour toutes ses réponses...

    Je suis passer par un fichier temporaire pour résoudre le problème.
    L'image qui etait envoyé et stockée me prenait beaucoup de place "javeheapspace" , je suis donc passer par un fichier temporaire qui me recréer l'image et la stocke, j'avais un problème de référencement qui est résolu en recréant un objet 'propre' en passant par ce fichier temporaire.
    Voici la partie du code final la variable qui me posait problème a stocker était 'img' la nouvelle étant 'imgBouchon1' .

    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
     
    ObjectInputStream dis = new ObjectInputStream(conn.getInputStream());	
    int readLength=dis.readInt();
    int currentsize=0;
    byte[] buffer=new byte[readLength];
    int ch =0;
    while (currentsize<readLength) {
    	if(readLength-currentsize>2048)
    		ch = dis.read(buffer,currentsize,2048);
    	else
    		ch = dis.read(buffer,currentsize,readLength-currentsize);
    	currentsize += ch;
    }
    ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
    BufferedImage bi = ImageIO.read((InputStream) bais);
    Image img=Toolkit.getDefaultToolkit().createImage(bi.getSource());
    		   	////
    Graphics2D g2d = bi.createGraphics();
    g2d.drawImage(img,  new AffineTransform(), null);
    g2d.dispose();
    OutputStream os;
    try {
    	os = new FileOutputStream("d:\\fichiertemp.jpg");
    	JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
    	encoder.encode(bi);
    	os.flush();
    	os.close();
    } catch (FileNotFoundException ex) {
    	ex.printStackTrace();
    } catch (IOException e) {
    	e.printStackTrace();
    }
    imgBouchon1 =new ImageIcon("d:\\fichiertemp.jpg").getImage() ;

  11. #11
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 872
    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 872
    Points : 22 939
    Points
    22 939
    Billets dans le blog
    53
    Par défaut
    Ok, mais pourquoi la ligne Image img=Toolkit.getDefaultToolkit().createImage(bi.getSource()); ?

    Hum non en fait après relecture ça m'a l'air pas encore tout à fait au point tout ça. A noter que la classe File dispose de methodes permettant de creer des fichiers temporaires (qui sont effacés après usage).

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Apparement pour le :

    g2d.drawImage(img, new AffineTransform(), null);

    sinon l'image a un fond noir (je pense).

    Pour le fichier temporaire j'ai essayé mais ça me fait aussi une erreur de mémoire.

  13. #13
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 872
    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 872
    Points : 22 939
    Points
    22 939
    Billets dans le blog
    53
    Par défaut
    Un peu plus de temps pour lire ce code ce matin...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ObjectInputStream dis = new ObjectInputStream(conn.getInputStream());
    Pourquoi un ObjectInpuStream ? Tu n'utilises plus la serialization desormais il me semble

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    BufferedImage bi = ImageIO.read((InputStream) bais);
    Image img=Toolkit.getDefaultToolkit().createImage(bi.getSource());
    		   	////
    Graphics2D g2d = bi.createGraphics();
    g2d.drawImage(img,  new AffineTransform(), null);
    g2d.dispose();
    Bon la j'avoue que je ne comprend absolument pas l'interret de ce bloc...
    Tu recuperes l'image via ImageIO, tu en crees une copie via Toolkit et tu recopies cette copie dans l'original avec une transformation indentitaire... Wooo, faut se calmer la, sauf si tu as mal fait ton boulot de l'autre cote de la socket, le premier appel est largement suffisant, le reste c'est de la perte de memoire et de temps CPU.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    OutputStream os;
    try {
    	os = new FileOutputStream("d:\\fichiertemp.jpg");
    	JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
    	encoder.encode(bi);
    	os.flush();
    	os.close();
    } catch (FileNotFoundException ex) {
    	ex.printStackTrace();
    } catch (IOException e) {
    	e.printStackTrace();
    }
    imgBouchon1 =new ImageIcon("d:\\fichiertemp.jpg").getImage() ;
    Donc une fois ton image recuperee tu la sauvegardes en JPEG puis la reouvres pour en faire une ImageIcon ??? Et y a un interret particulier ?
    Si ton but etais de produire du JPEG tu pouvais le faire directement a la source avant de l'envoyer sur la socket alors qu'apparement (on a pas le code donc on ne peut pas voir) tu l'envoie brut telle quelle. Pareillement, tu peux utiliser un vrai fichier temporaire ou tout faire en memoire, ImageIO supporte egalement le JPEG, pourquoi passer par JPEGImageEncoder (qui est si je ne m'abuse l'ancien codec non-officiellement supporte). De meme pas besoin de passer par un fichier pour creer une ImageIcon.

    sinon l'image a un fond noir (je pense).
    Faudrai penser a verifier... tant l'image avant son envoie sur la socket qu'apres sa reception.

    Pour le fichier temporaire j'ai essayé mais ça me fait aussi une erreur de mémoire.
    Code ?????????????????

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

Discussions similaires

  1. Comment envoyer mes images dans MySQL(PHP4)
    Par Charlie de Bolton dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 27/03/2007, 02h11
  2. Réponses: 14
    Dernier message: 14/03/2007, 20h32
  3. Réponses: 3
    Dernier message: 19/09/2006, 16h36
  4. [PHP-JS] charger plusieurs images sur le serveur
    Par ehmppowa dans le forum Langage
    Réponses: 4
    Dernier message: 13/12/2005, 17h22

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