Bonjour,
connaitriez-vous un moyen de passer un java.awt.Image à un OutputStream en le mettant au format jpg? ceci sans passer par ImageIO
Version imprimable
Bonjour,
connaitriez-vous un moyen de passer un java.awt.Image à un OutputStream en le mettant au format jpg? ceci sans passer par ImageIO
Alors avant que ImageIO ne soit integre au JDK/JRE il y avait un encodeur/decodeur de Sun pas officiellement supporte car situe dans le package com.sun.image.codec.jpeg (il peut donc ne pas etre present dans des JRE fournis par d'autres vendeurs). Mais je sais pu ou se trouve la doc de ces classes ; bon coup de bol j'ai encore du vieux code (plus du tout utilise depuis la disponibilite ImageIO) qui utilise ca.
Code:
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 import java.awt.*; import java.io.*; import com.sun.image.codec.jpeg.*; try { // Gets the encoder. JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outStream); // Gets the parameters object. JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image); param.setQuality(quality, false); // Encode the image. encoder.encode(image, param); } catch (ImageFormatException ife) { ... } ... try { JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(inStream); //JPEGDecodeParam param = decoder.getJPEGDecodeParam(); //decoder.setJPEGDecodeParam(param); BufferedImage image = decoder.decodeAsBufferedImage(); } catch (ImageFormatException ife) { ... }
oh yeah!
tu me file un sérieux coup de main là.
merci mille fois
eh eh eh
trop trop bon toi !
ca marche à la perfection !!!
Merci beaucoup beaucoup beaucoup !!!
ImageIO me faisait de la m**** concernant les envoi vers le flux outputstream de la socket
Quel probleme as-tu avec ImageIO ? L'utilisation des classes com.sun.* est fortement deconseillee car elles peuvent changer sans aucun avis. De plus elles ne sont pas supportees donc ce n'est meme pas la peine de demander de l'aide a leur sujet sur les forums officiels :))
eh bien, c'est treès simple
tentes d'envoyer 100 images jpg à un client, même en attendant que celui-ci soit pret
coté serveur:
coté client:Code:
1
2
3
4
5
6 while(i++<100) { while(!bufferedReader.readLine().equals("READY")) sleep(10); ImageIO.write(image[i], "jpg", client.getOutputStream()); }
chez moi, pour le client, ça affiche une adresse valide puis que des null.Code:
1
2
3
4
5
6
7 while(true) { printWriter.println("READY"); printWriter.flush(); bufferedImage = ImageIO.read(serveur.getInputStream()); System.out.println("image="+bufferedImage); }
je n'ai plus ce probleme avec la solution de bouye
J'ai utilise ImageIO pour developper un serveur et un client de streaming video et je n'ai eu aucun probleme avec. Je doute que l'ImageIO soit le coupable dans ton cas. Le problement vient surement de la gestion des flux (surement des flush et autres choses amusantes a placer aux endroits voulus). Enfin du moment que ton code marche... :)
Mais il faut bien se souvenir que c'est une solution qui :
1) n'est pas officiellement supportée.
2) peut ne pas être disponible sur toutes les JVM existantes.
3) peut ne pas marcher avec des futures versions de Java (même avec les JVM de Sun). Ces classes pouvant être modifiées sans préavis ou carrément éliminées.
Oui ^^ C'est dommage car les classes privees/non documentees du JDK contiennent quelques perles. Par exemple il y a un support des protocoles Telnet, SMTP et FTP inclus dans un package sun.*. Il y a aussi un serveur HTTP qui traine.
Cela dit il faut bien savoir que toutes ces classes privees (une des plus connues etant SwingUtilities2) nous sont indispensables. Elles nous permettent de changer des implementations sans modifier les API publiques et garantir une tres bonne compatibilite d'une version du JDK a l'autre. Elles nous permettent aussi de pouvoir corriger des bugs sans modifier les API publiques. Bref, c'est pas pour embeter le monde ^^
Oui mais là quand même......... pfffffffffCitation:
Par exemple il y a un support des protocoles Telnet, SMTP et FTP inclus dans un package sun.*. Il y a aussi un serveur HTTP qui traine.
Hum qui c'était qui disais que des gens se pleignaient de la taille du JRE ?
:lol:
N'y a t'il pas aussi des raison légales ? Je veux dire, sauf si je reconte des co@~#{, j'avais lu qq part que Sun avait retiré le support de JavaMail et des type MIME (alors que c'était bien présent dans les 1ère beta du JDK 1.2 ou 1.3) car une compagnie qui vendait un support commercial du mail pour Java avait menacé Sun de procès pour position dominante/de monopole. Arh, impossible de me souvenir où j'avais vu ca... dans un bouquin d'Oreilly il y a déjà bien 5~6 ans je crois ; mais lequel ?
Edit - après un tour rapide dans mes bouquins impossible de retrouvrer la référence. Bon j'espère que j'aurais pas inventé cette histoire :marteau:
Ca depend oui. Mais toutes les classes sont la pour une raison bien precise. Par exemple le support du protocole FTP permet de telecharger des images avec la classe URL et l'ImageIO, etc.
Stop the press ! J'ai retrouvé ... et ce n'était pas à propos de JavaMail (quoi qu'il faudra qu'on m'explique pourquoi les type MIME ont été retirés)... mais à propos de cet encodeur JPEG justement :!:
D'après Java 2D Graphics chez O'Reilly (page 183 de l'édition US) les "bruits" et autres plaintes générés par une société du nom de Activated Intelligence sont la principale raison pour laquelle Sun a déplacé l'encodeur JPEG dans un package non-documenté. Bien évidement Activated Intelligence vendait des codecs Java pour divers format d'image. Et l'auteur d'annoncer à l'époque (le livre date de 1999) que Sun travaillait sur ce qui allait devenir ImageIO.
Maintenant que je me suis rafraichit la mémoire un bon coup c'est vrai que l'encodeur JPEG était dans les packages standards dans les premières betas du JDK 1.2
Cela dit le codeur/decodeur JPEG du JDK est pas le meilleur qui existe. On trouve des bibliotheques tierces de meilleure qualite. Enfin la difference est imperceptible pour un usage normal.
La doc de ce package est disponible dans la documentation du JDK plus exactement ici <endroit à la doc est installée>\guide\2d\api-jpeg\index.html.
En effet. Le code source est meme dans le src.zip. Bon je savais bien que j'allais dire une connerie ce soir ^^ Mea culpa.
:) ... Il est tard... encore que un peu moins là où je suis ... mais hum je commence à avoir sommeil moi :sleep:
C'est bien que vous discutez sur le sujet, j'en apprend encore et encore avec vous.
je suis vraiment content que mon prog marche.
Mainenant, je vais améliorer le prog pour pouvoir appliquer des filtres.
J'ai fait des test avec ImageIO et la solution com.sun.jpeg, j'en déduit que:
ImageIO.write fait parfaitement son boulot mais c'est pas le cas pour ImageIO.read().
Il faut dire aussi que j'ai une socket
et ImageIO va lire dans cette socket:
coté serveur:
coté client:Code:
1
2
3
4
5
6
7
8
9 PrintWriter pw = new PrintWriter(socket.getOutputStream()); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); while(true) { image = getImage(); pw.println("image"); ImageIO.write(image, "jpg", socket.getOutputStream()); br.readLine(); }
si je met bmp a la place de jpg, y'a pas de souci pourtant.Code:
1
2
3
4
5
6
7
8
9
10 BufferedReader br = new BufferedReader(new PrintWriter pw = new InputStreamReader(socket.getInputStream())); PrintWriter pw = new PrintWriter(socket.getOutputStream()); while(true) { br.readLine(); image = ImageIO.read(); repaint(); pw.println("READY"); pw.flush(); }
j'enleve le tag résolu pour que se réinteresse a ce probleme meme s'il est pseudo résolu
Voilà c'est résolu!
Je vous explique ma procédure:
du coté serveur:
1- image -> byte[] (grace a ImageIO.write et ByteArrayOutputStream)
2- envoi ascii byte[].length
3- envoi binaire byte[]
coté client:
1- reception taille tableau -> byte[n]
2- DataInputStream + readFully du byte[]
3- ByteArrayInputStream(byte[])
4- ImageIO.read du ByteArrayInputStream
ce que j'en déduit:
le client tente de lire ds la socket ce que le serveur n'a pas eu le temps d'envoyer completement, et vu que le flush a l'air automatique coté serveur, ça c'est produit!
Donc ImageIO.read n'attend pas que le tableau soit complet pour effectuer son travail
et ImageIO.write flush a chaque caractere.
Je me trompe peut etre, mais ca a l'air d'etre ca