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

avec Java Discussion :

In/out putStreams (bytearray, piped, image)


Sujet :

avec Java

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4
    Points : 3
    Points
    3
    Par défaut In/out putStreams (bytearray, piped, image)
    Bonjour,

    J'ai un soucis avec des input/outputStreams.

    Je travaille sur un programme permettant de compresser/decompresser des images au format médicale. L'algo est le suivant :

    L'image A etant compréssé d'un certain format.

    - on decompresse A et on obtient B en raw
    - on compresse B dans le format voulut et on obtient C

    J'ai pu récupérer du code permettant de faire tout ça mais utilisant des FileInput/outputstream. Ce qui ma choqué c'est que cela oblige a sauvegardé chaque étape (B et C) dans un fichier et donc sur le disque dur plutôt que de garder le tout en ram. Pour moi le fait d'accéder au disque dur est énormément couteux en temps j'ai donc voulut modifier tout ça en n'utilisant uniquement la ram.

    Pour cela j'ai remplacé les FileStream par des ByteArrayStream mais cela a pour effet d'être encore plus long !! il y a donc quelquechose que je ne saisis pas.

    Mon deuxième problème est que lorsque j'ai voulut utiliser des PipedStream j'ai été bloqué car finalement peut importe le stream utilisé au depart il est convertit en ImageStream. Il m'est donc impossible de récupérer l'input car l'output est copié dans un ImageStream.

    Voici du code pour illustrer mes dire :

    au depart :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    File f = new File(Path);
    File decompress = File.createTempFile("img",".dcm");
    File imgFinal =  File.createTempFile("imgFinal",".dcm"); 
     
    TranscoderMain.launchCompression('d', "100", f, decompress);
    TranscoderMain.launchCompression(comp, quality, decompress, imgFinal);
    avec ma modif

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    File f = new File(Path);
    FileInputStream fis = new FileInputStream(file);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ByteArrayOutputStream outFinal = new ByteArrayOutputStream();
     
    TranscoderMain.launchCompression('d', "100", fis, out);
    TranscoderMain.launchCompression(comp, quality, new ByteArrayInputStream(out.toByteArray()), outFinal);
    la fonction launchCompression

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static int launchCompression(char c, String quality, InputStream is, OutputStream os){		
     
            try {
                setInput(this.iis = ImageIO.createImageInputStream(is));
                setOutput(this.ios = ImageIO.createImageOutputStream(os));
     
            (...)
     
    }

    Donc je pense fortement que le problème vient des ImageStream mais il doit bien y avoir un moyen d'optimisé cela sans passé par des accès disques totalement inutile.

    Merci D'avance.

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    A titre d'information : quel est la taille des fichiers à chaque étape ?


    Sinon, ce serait bien d'avoir le code de la méthode launchCompression(), car je pense qu'il est possible de faire plus simple en encapsulant des flux.


    a++

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Si ton image raw est grosse, tu peux utiliser new ByteArrayOutputStream(taille) pour éviter les redimenssionnement.

    Sinon, les pipedstream devraient fonctionner sans problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    out = new PipedOutputStream();
    in = new PipedInputStream(out);
    Thread t1 = new Thread (){
    .....
    TranscoderMain.launchCompression('d', "100", fis, out);
    .....
    }
    t1.start(); // produce decompressed image in background
    TranscoderMain.launchCompression(comp, quality, in, outFinal); // compress
    t1.join(); // shouldn't be needed

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    La taille des fichiers est variable selon l'image et la compression, si la question était de savoir si les fichiers sont bien créé et remplit la réponse est oui je peux tous les ouvrir et ils contiennent exactement ce qu'il faut.

    La fonction LaunchCompression est plutôt compliqué elle fait appel a une librairie et il y a pas mal d'accès de partout du type :

    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
     
     
    final PipedOutputStream out = new PipedOutputStream();
    final PipedInputStream in = new PipedInputStream(out);
    final PipedOutputStream outFinal = new PipedOutputStream();
    PipedInputStream fis = new PipedInputStream(outFinal);
     
    siis = new SegmentedImageInputStream(iis, itemParser);
     
    ...
     
    dsIn.writeHeader(ios, encodeParam, Tags.Item, VRs.NONE, len);
    copy(iis, ios, len);
     
    ...
     
    ios.seek(itemPos);
    dsIn.writeHeader(ios, encodeParam, Tags.Item, VRs.NONE, itemLen);
    ios.seek(endPos);
    ios.flushBefore(endPos);
    et pas mal d'autre choses dans ce style donc il faudrait un certain temps pour décortiquer tout les accès fait par les différentes fonctions et sous-fonction

    Pour les PipedStream en effet j'ai réussit dans votre exemple mais au quatrième ça plante :

    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
     
     
    Thread t1 = new Thread (){
    			public void run(){
    				TranscoderMain.launchCompression('d', "100", inF, out);
    			}
    		};
     
    		t1.start();
     
    		Thread t2 = new Thread (){
    			public void run(){
    				TranscoderMain.launchCompression(comp, quality, in, outFinal);
    			}
    		};
     
    		t2.start();
     
     
    		ServletOutputStream  sos = response.getOutputStream();
     
    		byte[] b = new byte[speed];
    		int readSize = 0;
    		for(readSize = fis.read(b); readSize >= 0;readSize = fis.read(b)) {//Erreur ici au read => java.io.IOException: Pipe broken => Write end dead 
    			sos.write(b, 0, readSize);
    			size += readSize;
    		}
    S'il n'y a pas de solution ou que cela implique une modification interne de la fonction LaunchCompression et de tout les accès au flux je laisserais tombé tampis

  5. #5
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ghetolay Voir le message
    La taille des fichiers est variable selon l'image et la compression, si la question était de savoir si les fichiers sont bien créé et remplit la réponse est oui je peux tous les ouvrir et ils contiennent exactement ce qu'il faut.
    En fait si tu connais même approximativement la taille du fichier final tu peux optimiser un peu les ByteArrayOutputStream en l'initialisation à la bonne taille comme l'indique tchize_.
    Si les fichiers sont volumineux cela peut apporter un gain intéressant, car cela évites plusieurs redimensionnement du tableau de bytes interne.




    Citation Envoyé par ghetolay Voir le message
    Pour les PipedStream en effet j'ai réussit mais je ne gagne rien en temps d'éxécution par rapport au FileStream
    Le problème c'est que tu passes en multithread et donc avec beaucoup plus de synchronisation. Donc ce que tu gagnes en évitant des d'E/S disques, tu le perd en synchro entre thread...


    Citation Envoyé par ghetolay Voir le message
    S'il n'y a pas de solution ou que cela implique une modification interne de la fonction LaunchCompression et de tout les accès au flux je laisserais tombé tampis
    Perso j'aurais opté pour une encapsulation de flux, un peu comme le fait les ZipOutputStream, etc.

    Mais cela dépend fortement de ton algo de compression...


    a++

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    comme t'as deux threads, tu dosi attendre qu'ilsaien fini le travaille (t1.join(); t2.join(); ) sinon tu va envoyé à ton utilisateur une réponse pas encore construite. La logique voudrais que tu fasse d'ailleur un deuxième paire de pipedstream entre la compression (pipedoutputstream) et ce que tu lit pour renvoyer au client par http (pipedinputstream) pour etre entièrement indépendant du disque Dans ce dernier cas, pas de join! c'est ton pipedinputstream final qui va faire avancer tes thread au fur et à mesure de la lecture

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Merci pour cette aide, finalement j'ai spécifié la taille de mes byteArray et effectivement je gagne quelques millisecondes

    Merci encore

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 21/03/2013, 13h32
  2. [J2SSH] Channel'In/Out'putStream problème
    Par Cyrodiil dans le forum API standards et tierces
    Réponses: 4
    Dernier message: 30/11/2010, 11h21
  3. Réponses: 4
    Dernier message: 20/09/2009, 11h12
  4. Fade In/Fade Out avec div avec background Image
    Par Cdic83 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 25/08/2008, 21h02
  5. Tableau d'images et ACP out of memory
    Par soeursourire dans le forum Images
    Réponses: 6
    Dernier message: 08/02/2008, 12h03

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