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 :

Alimenter une image byte[] à partir d'un String


Sujet :

AWT/Swing Java

  1. #1
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut Alimenter une image byte[] à partir d'un String
    Bonjour,

    Je dois alimenter une image byte[] transmise au programme via un String.
    (en fait l'image est tirée d'un colonne BLOB d'une BDD)
    la bête conversion byte[i] = (byte)string.substr(i,1) semble fonctionner. Seulement lorsque je veux affecter l'image avec mon buffer byte[], j'obtiens une erreur (en gros le format image n'est pas correct)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    img = Toolkit.getDefaultToolkit().createImage(buffer) ;
    Quelqu'un connait-il une meilleure façon de procéder ?

  2. #2
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Gné ?

  3. #3
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Ok, résolu dans le forum Général -> Language.

  4. #4
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    J'avais fondé de grands espoirs sur la méthode getBytes() de la classe String, mais il semblerait qu'elle ne soit pas top pour convertir des char en byte...

    j'affiche bien une image, mais elle est méconnaissable.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    byte[] buffer = stringimage.toString().getBytes() ;
    img = Toolkit.getDefaultToolkit().createImage(buffer) ;
    si quelqu'un a une idée...

  5. #5
    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
    Il est possible que tu ais un probleme d'encodage de character lors de l'utilisation de la methode getBytes() (resp dans l'autre sens quand tu mets ton image dans ta base). N'y a-t-il aucun moyen de manipuler un tableau d'octets tout du long (desole les BD ne sont pas mon fort).

    Sinon, peux-tu comparer ce tableau d'octet avec le contenu du fichier JPEG ou GIF source sur le disque (puisque Toolkit.createImage() demande une image dans ce format) histoire d'essayer de voir en quoi ces deux flux different ?

    Pourquoi avoir resolu le topic si ca ne fonctionne toujours pas ?

  6. #6
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    merci pour cette réponse.
    Je suis en train de sombrer en pleine 5ème dimension, maintenant.
    Si je compare le tableau de bytes que je créé à partir des chaines de caractère et celui créé par la lecture de l'image en base, ils sont identiques !
    et pourtant, l'un créé une image impec et l'autre un magma informe

  7. #7
    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
    Aille, meme taille et contenu 100% indentique ? effectivement... Euh... j'ai encore moins d'idee qu'avant sur le coup, la.
    Sinon essayer d'enrober le tableau d'octets dans un ByteArrayInputStream et d'utiliser ImageIO (utiliser la methode read(InputStream input)) pour voir s'il peut generer une image (eventuellement essaye de forcer le format a utiliser - voir methode getImageReadersXXXX()). Mais bon, si ca ne fonctionne pas avec Toolkit...

  8. #8
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    En fait, je n'ai comparé que le 20 premiers et derniers octets.
    Je vais refaire le test sur une image de 5 pixels de coté et comparer tous les octets.
    En tous cas, merci pour les tuyaux.

  9. #9
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Episode 2:
    J'ai donc fini par comparer les 2 tableaux octet par octet.
    les 2 tableaux font 13548 bytes.

    seuls 280 sont différents et sur 5 valeurs différentes seulement:
    -99
    -112
    -113
    -115
    -127

    qui sont tous interprétés 63 avec getByte().

    qu'est-ce que ces 5 caractères ont d'extraordinaire ?
    comment avec seulement 280 points différents sur 13548 mon image est-elle totalement méconnaissable ?

  10. #10
    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
    La la reponse depend du format d'image utilise mais c'est largement suffisant pour faire planter un format compresse tel que JPEG qui doit utiliser des structures de stockages internes. Sur du PNM (PBM, PGM, PPM) ou n'importe quel format a plat non-compresse c'est clair qu'on pourrait facilement voir l'image.

    Donc le probleme se trouve du cote de l'encodage de ton tableau d'octets en chaine de charactere dans la base et/ou du cote du decodage de cette chaine de texte en tableau d'octets.

    Verifie que tu utilises bien le meme codage (quite a le specifier manuellement) des deux cotes ou essaie de voir si tu ne peux pas directement stocker le tableau d'octet dans la base au lieu de la chaine.

  11. #11
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Ce sont des octets dans la base, raison pour laquelle j'affiche bien l'image lorsque je la lis avec le driver JDBC.
    Ma problématique, est que, pour rester dans la session en cours de mon programme tiers, je veux me passer de la connexion JDBC. Je dois donc récupérer l'image depuis ce programme. Hors je n'ai droit qu' à NUMBER ou VARCHAR. Je passe donc l'image au format chaîne de caractères.

    voici le code avec lequel je récupère l'image via le driver JDBC

    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
     
        ...
        // Create a Statement
        Statement stmt = conn.createStatement ();
     
        req  = "select " + sColumn + ", LENGTH(" + sColumn + ") " ;
        req += "from " + sTable + " where " + sLookup + "=" + iDentifiant ;
        log("Lecture() : execute query="+req) ;
        ResultSet rset = stmt.executeQuery ( req );
        while (rset.next ())
        {
          // Get the lob
          blobImage = ((OracleResultSet)rset).getBLOB (1);
          iLength = rset.getInt(2) ;
        }
        // Close all resources
        rset.close();
        stmt.close();
     
        log("Lecture() : transform the BLOB length="+iLength) ;
        if( iLength > 0 )
        {
          InputStream instream = blobImage.getBinaryStream();
          // Create temporary buffer for read
          HandleImage.buffer2 = new byte[iLength];
          int length = 0;
          // Fetch data  
          while ((length = instream.read(HandleImage.buffer2)) != -1)
          {
            log("Lecture() : Read " + length + " bytes: ");
          }
     
          // Close input stream
          instream.close();    
          conn.close(); 
          img = Toolkit.getDefaultToolkit().createImage(HandleImage.buffer2) ;
    Dans ce cas, il n'y a aucun problème de conversion

  12. #12
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Seulement 5 octets mal interprété sur 255, je ne vois plus qu'un bug avec getBytes().
    Est-il possible de remplacer cette fonction et si oui, comment ?

  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
    Tu peux specifier toi-meme un encodage :

    Citation Envoyé par javadoc
    public byte[] getBytes(String charsetName)
    throws UnsupportedEncodingException
    Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array.
    Ou tu peux aussi toi meme iterrer sur tous les characteres de la chaine et ne prendre que les 8 bits de poids faible (puisque les caracteres Java font 16 bits). Quelques chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int charNumber = str.length();
    byte[] bytes = new byte[charNumber];
    for (int i = 0 ; i < charNumber ;  i++) {
      bytes[i] = (byte)((str.charAt(i) & 0xFF) >> 0);
    }
    Mais encore une fois il faut egalement verifier l'encodage de la methode qui met l'image dans la base en la convertissant en chaine de charactere. L'erreur peut aussi venir de la.

  14. #14
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Merci, bouye, de t'accrocher encore à cette pénible enfilade.
    J'ai bien sur testé les encodages dans getBytes(). Toute autre valeur que celle par défaut (c'est à dire rien) donne des résultats encore plus sordides.
    Le problème ne vient pas de l'encodage de l'image puisque celle-ci est est parfaites lorsque je la lis depuis JDBC.
    Et le fait que seuls, 5 caratères sur 255 soient mal interprétés, ne semble pas pencher pour une erreur de jeu de caractères...
    je vais essayer ta méthode pour décoder les bytes un par un...
    Encore merci

  15. #15
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    En appliquant ton code, la quasi totalité des caractères sont mal interprétés...
    Quel est l'interêt d'un décallage de zéro ? ( >> 0 )

  16. #16
    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
    Ici a rien... d'ailleurs j'aurai probablement du ecrire (i >> 0) & 0xFF plutot avec (i >> n) & 0xFF avec n dans [0, m] et m = 1 si i char ou short, m = 3 si i int et m = 7 si i long ; permet de recuperer l'octet de poids n.

    Qu'entends-tu pas mal interprete ? Tu veux dire different du flux source (aka image sur le disque).
    Ici, on se contente de prendre les 8 bits de poids faible, sachant qu'un charactere java est constitue de 16 bits et que Java est big-endian. Sinon tu peux remplacer le 0 par un 1 et voir ce que ca donne.. mais la ca retournerai les 8 bits de poids fort et normalement ce n'est pas la bonne demarche a suivre.

    Au risque de me repeter... peut-on voir le code qui prend une image, la convertit en chaine et la met dans la base ? (l'autre cote du mirroir donc).

  17. #17
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    L'image n'est pas codé sous forme de chaîne dans la base, mais sous sa forme binaire. C'est le transfert entre mon appli et la java bean qui nécessite une transformation en string.

    Voici le code pl/sql qui extrait des chunks de l'image de la base;

    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
    FUNCTION Get_Chunk RETURN VARCHAR2
      IS
        LN$amt  NUMBER := GN$Chunk ;
        LR$raw  RAW(32000);
      BEGIN
        LN$amt := GN$Chunk ;
        -- Read the BLOB
        dbms_lob.READ(GL$Blob, LN$amt, GN$Pos, LR$raw);
        GN$Pos := GN$Pos + LN$amt;
        LN$amt := GN$Chunk;
        RETURN utl_raw.cast_to_varchar2(LR$raw) ;
      EXCEPTION
        WHEN OTHERS THEN
            RETURN NULL ;
      END Get_Chunk ;
    Le binaire (raw) est casté en varchar2 (string) avant d'être renvoyé.

    Mon appli (Forms pour ne pas la nommer) ne peut transferer au bean que du char, number ou date.

    Et par mal interprété, je compare chaquee octet du tableau byte[] obtenu avec getBytes() avec celui que je lis depuis le Java avec le driver JDBC. Cette image lue est parfaite et c'est avec celle-ci que je constate que 5 caractères seulement sont mal interprétés par la fonction getBytes() puisqu'ils sont différents de ceux du tableau lu avec JDBC.

    Le but, je le rappelle, est de me libérer de la lecture en base avec JDBC.

  18. #18
    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
    Evidement... je me suis fait avoir par ma propre demande... je ne pige rien au PERL. J'imagine cependant que comme il s'agit d'un cast direct on a bien des chars 8 bits equivalents des bytes/octets retires de la bases.

    Comment se fait ensuite le transfert entre cette partie et le beans pour que Java recupere sa chaine de chars 16 bits ? via le reseau ? Via JNI ? (oui je suis toujours a cours d'idees)

    PS : j'oubliais, sinon plutot qu'un masquaget et un decalage, un simple cast (byte b = (byte)c;) devrait suffire et permettre d'obtenir le meme resultat.

  19. #19
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Les chaînes de caratères sont récupérées dans l'application Forms et transmises au bean via une built-in interne (Set_Custom_Property( bean, la_chaine )).
    Le bean récupère un objet dont il extrait la chaine en question (String)objet.value.

    Je pense que l'ensemble marche à peu près correctement. La seule interrogation concerne ces 5 caractères (et ces 5 seulement) qui sont mal interprétés par getBytes(). Je n'arrive pas à comprendre pourquoi ces 5 seulement!
    Mais tu sais déjà tout ça...

    En tout cas, merci pour ta dispo, toi qui te trouve à l'autre extrémité du monde!

Discussions similaires

  1. [Débutant] Ranger une image Byte à partir d'un reader possible?
    Par yazmat dans le forum ASP.NET
    Réponses: 12
    Dernier message: 21/08/2014, 11h56
  2. Problème de création d'une image BMP à partir d'un byte[]
    Par Dark_Alex69 dans le forum Interfaces Graphiques en Java
    Réponses: 4
    Dernier message: 28/03/2010, 17h32
  3. reconstitution d'une image a partir d'un tableau de bytes
    Par guian dans le forum Entrée/Sortie
    Réponses: 17
    Dernier message: 04/12/2008, 17h54
  4. Réponses: 1
    Dernier message: 03/11/2008, 16h36
  5. Réponses: 4
    Dernier message: 26/08/2004, 09h01

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