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

C++/CLI Discussion :

R�cup�rer une image depuis un IntPtr


Sujet :

C++/CLI

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre confirm� Avatar de Baud10
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    66
    D�tails du profil
    Informations personnelles :
    �ge : 38
    Localisation : France, C�te d'Or (Bourgogne)

    Informations forums :
    Inscription : Mai 2006
    Messages : 66
    Par d�faut R�cup�rer une image depuis un IntPtr
    Bonjour,

    J'utilise la librarie FMOD pour lire des fichiers audio et j'aimerai r�cup�rer les ID3 Tag v2. J'y arrive, mais je n'arrive pas a r�cup�rer l'image (si elle existe) dans le fichier.

    Je sais qu'elle est enregistr� dans un TAG appel� "APIC" et de type FMOD.TAGDATATYPE.BINARY.

    J'arrive a r�cup�rer le FMOD.TAG qui est cens� contenir la photo.
    tagphoto.datalen retourne 48108 (48 ko �a parait beaucoup pour un JPG de petite taille ?).

    Pour r�cup�rer les tag string (artiste, album, titre), je dois faire: Marshal.PtrToStringAnsi(montag.data). Mais s'il s'agit d'un type BINARY je ne sais pas quoi faire.

    Je ne suis pas expert en la mati�re, si quelqu'un pouvait me donner un coup de pouce pour arriver jusqu'a une Image/Bitmap

    Pourquoi d'ailleurs, le site officiel parle du tag PIC au lieu de APIC? (http://www.id3.org/id3v2-00)

    Merci d'avance

  2. #2
    R�dacteur/Mod�rateur


    Homme Profil pro
    D�veloppeur .NET
    Inscrit en
    F�vrier 2004
    Messages
    19 875
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 43
    Localisation : France, Paris (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur .NET
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 19 875
    Par d�faut
    Il faudrait voir dans la documentation ce que repr�sente ce IntPtr... �a pourrait par exemple �tre un HBITMAP (handle Windows pour une image), auquel cas tu pourrais r�cup�rer l'image en faisant juste �a :

    Code C# : S�lectionner tout - Visualiser dans une fen�tre � part
    Image img = Image.FromHBitmap(montag.data);

    Si c'est l'addresse des donn�es de l'image, je vois 2 options :

    - utiliser un UnmanagedMemoryStream et l'utiliser pour cr�er l'image avec Image.FromStream. Sans doute la solution la plus efficace, mais l'inconv�nient c'est que �a utilise des pointeurs et que �a ne peut donc s'utiliser que dans du code unsafe

    - Copier les donn�es dans un buffer manag� avec Marshal.Copy, cr�er un MemoryStream sur ce buffer, et cr�er l'image avec Image.FromStream. Un peu moins rapide puisqu'il faut d'abord copier les donn�es, mais plus s�r...

  3. #3
    Membre confirm� Avatar de Baud10
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    66
    D�tails du profil
    Informations personnelles :
    �ge : 38
    Localisation : France, C�te d'Or (Bourgogne)

    Informations forums :
    Inscription : Mai 2006
    Messages : 66
    Par d�faut
    Le UnmanagedMemoryStream fonctionne. J'ai eu du mal mais �a fonctionne.

    J'avais tent� une alternative avec
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    GCHandle gc = GCHandle.FromIntPtr(newtag.data);
    mais j'obtiens in�vitablement l'erreur fatale
    ExecutionEngineException...
    Bref, mon gros souci maintenant est que avant l'image, je r�cup�re le header, d'une taille variable (d'apr�s mes observations soit 13, soit 14 octets, puis a ajouter a �a, une chaine allant jusqu'a 64 octets)... Je gal�re a trouver pourquoi des fois 13 et des fois 14 ^^

  4. #4
    Membre confirm� Avatar de Baud10
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    66
    D�tails du profil
    Informations personnelles :
    �ge : 38
    Localisation : France, C�te d'Or (Bourgogne)

    Informations forums :
    Inscription : Mai 2006
    Messages : 66
    Par d�faut
    Je pense avoir r�solu mes probl�mes...
    Je poste mon code a toute fins utiles, j'imagine que vous en trouverez a redire...

    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
    unsafe
                            {
                                try
                                {
     
                                    // on recherche la présence du TAG APIC
                                    TAG newtag = GetTag("APIC", snd);
                                    if (newtag.datalen > 0 && newtag.datatype == TAGDATATYPE.BINARY) // il est présent et non vide
                                    {
                                        // on charge dans un flux le tag
                                        UnmanagedMemoryStream stream = new UnmanagedMemoryStream((byte*)newtag.data, newtag.datalen);
     
                                        // l'entête mesure au minimum 12 + une chaine (compise entre 0 à 63 octets + \0 final)
                                        int tailleEntete = 12, tailleChaine = 1;
     
                                        // on créé un tableau de travail qui contiendra le tag
                                        byte[] managed = new byte[newtag.datalen];
                                        // on charge le flux dans notre tableau
                                        stream.Read(managed, 0, (int)newtag.datalen);
                                        // si l'octet N°10 vaut 101, alors la taille de l'entête n'est pas 12 mais 13
                                        if (managed[9] == 101) tailleEntete = 13;
                                        // on essai de lire la suite après l'entête : la chaine
                                        stream.Seek(tailleEntete, SeekOrigin.Begin);
                                        // on cherche l'octet qui vaut zéro à partir de ce point, qui indique la fin de la chaine
                                        for (; tailleChaine < managed.Length; tailleChaine++)
                                        {
                                            if (stream.ReadByte() == 0)
                                                break;
                                        }
                                        // on créé un flux qui ne contiendra que l'image (sans l'entête du TAG)
                                        MemoryStream mem = new MemoryStream(managed, tailleEntete + tailleChaine, (int)newtag.datalen - (tailleEntete + tailleChaine));
                                        // on affiche le champ image
                                        image.Visible = true;
                                        // on rempli le champ image avec l'image contenue dans le flux
                                        image.Image = Image.FromStream(mem);
                                    }
                                }
                                catch (Exception ex) { MessageBox.Show("Impossible de charger la miniature"); }
                            }

  5. #5
    R�dacteur/Mod�rateur


    Homme Profil pro
    D�veloppeur .NET
    Inscrit en
    F�vrier 2004
    Messages
    19 875
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 43
    Localisation : France, Paris (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur .NET
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 19 875
    Par d�faut
    Citation Envoy� par Baud10 Voir le message
    J'avais tent� une alternative avec GCHandle gc = GCHandle.FromIntPtr(newtag.data); mais j'obtiens in�vitablement l'erreur fatale ExecutionEngineException...
    oula... GCHandle c'est un handle du garbage collector vers un objet manag�. Ca n'a rien � voir avec un pointeur de m�moire non manag�e.... Donc forc�ment �a risque pas de marcher

    Sinon, j'ai pas analys� ton code en d�tail, mais pense � refermer les Streams que tu cr�es... le plus simple c'est de les utiliser dans un bloc using, comme �a tu es s�r qu'ils sont referm�s m�me en cas d'erreur

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. R�cup�rer une image depuis le systeme de fichier
    Par momedalhouma dans le forum JSF
    R�ponses: 5
    Dernier message: 18/06/2014, 02h31
  2. R�ponses: 3
    Dernier message: 06/08/2013, 12h43
  3. [MySQL] R�cup�rer une image depuis phpMyAdmin
    Par bonomsoleil dans le forum PHP & Base de donn�es
    R�ponses: 10
    Dernier message: 17/12/2008, 08h55
  4. R�ponses: 3
    Dernier message: 10/11/2008, 11h58

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