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++ Discussion :

Lire un BLOB Mysql en C++


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Juillet 2012
    Messages : 7
    Par défaut Lire un BLOB Mysql en C++
    Bonjour à tous,

    Après 3 jours de recherche , je bute contre un petit problème et j'en implore votre aide amis programmeur.

    Outils:

    -Visual Studio 2012
    -Langage C++
    -MFC

    Sujet:

    Je doit stocker et récupérer en base de donner mysql tout un tas de données. Tous cela se passe à merveille mais la présence d'un FAMEUX BLOB gâche mes nuits .Dans ce BLOB est contenu un fichier image de type jpeg ou bmp et c'est à la lecture du Blob via le code que je flanche. J'arrive actuellement à récupérer en lecture dans une CString tous les caractère hexadécimal contenus dans le champ.
    ( C'est caractère représente sans nuls doutes l'image stockée dans le BLOB)

    La questions:

    Comment interpréter et reconstruire l'image de départ et l'affectée a un PictureControl à partir de ma CString contenant toutes les valeurs hexadécimales ??

    La où j'en suis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CString test; // contiens tous les caractères hexadecimal
    CBitmap bmp;   
     
    CT2CA pszConvertedAnsiString (test);
    // construct a std::string using the LPCSTR input
    string Mystring (pszConvertedAnsiString);
     
    PBYTE ba = (PBYTE) Mystring.c_str();
     
    bmp.CreateBitmap(96,96,1,1,ba);
     
    m_picture->SetBitmap(bmp);
    A l'affichage j'obtiens un dessins blanc et noir ne représentant pas grand chose et surtout pas mon image de départ.

    J’espère avoir été clair , HELP , merci par avances.

    Cordialement,

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Le meilleur moyen pour récupérer l'équivalent d'un BLOB, c'est, à mon sens, de récupérer un tableau de (unsigned) char.

    Tu peux, par exemple, envisager de récupérer ces données dans un std::vector<unsigned char> qui me semble "idéal" pour cet objectif particulier

    Après, il faut savoir que l'utilisation que tu en feras dépendra essentiellement du type d'objet représenté par ton blob.

    Après avoir récupéré ton tableau de (unsigned) char, il faudra convertir ces données brutes en quelque chose d'utilisable qui correspond au type d'objet représenté, mais, à ce point, c'est trop dépendant des circonstances pour pouvoir t'aider de manière claire et précise ;

    NOTA: A moins de demander l'affichage des valeurs hexadécimale, il ne faut absolument pas tenter d'afficher les données sous forme de caractère, ne serait-ce que parce que certains caractères ne sont pas forcément affichables
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    un champ BLOB (binary large object) c'est ni plus ni moins que des données bruts. Ce sont les données que tu peux lire lorsque tu ouvres ton fichier en binaire.

    Pour les utiliser, tu dois avoir dans ton code quelque chose comme ça je suppose:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Image myImage;
    myImage.loadFromFile(filename);
    Ce qu'il te faut, c'est utiliser des méthodes généralement de la forme loadFromRaw(blobDatas);.
    Ou identifier le code qui ouvre le fichier et parse son contenu, pour parser ton blob.

    Pour le "stockage", un const unsigned char* serait idéal.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Hello

    Citation Envoyé par koala01 Voir le message
    Tu peux, par exemple, envisager de récupérer ces données dans un std::vector<unsigned char> qui me semble "idéal" pour cet objectif particulier
    Pas d'accord sur ce point : remplir le vector sera coûteux et n'a aucune valeur ajoutée, puisqu'on doit de nouveau accéder aux données brutes dans une structure qui va représenter l'image et se charger d'elles. Pour moi, un char* (éventuellement unsigned) couplé à la taille des données suffit amplement. Il faut être soigneux avec la mémoire, mais utiliser le vector ici n'aide pas puisqu'on part directement de données brutes.

    Citation Envoyé par Bousk Voir le message
    Ce qu'il te faut, c'est utiliser des méthodes généralement de la forme loadFromRaw(blobDatas);.
    Je pense que le code que BenoitYneste nous a montré

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    PBYTE ba = (PBYTE) Mystring.c_str();
     bmp.CreateBitmap(96,96,1,1,ba);
    m_picture->SetBitmap(bmp);
    Rempli ce rôle.

    BenoitYneste:

    Premier point: le stockage du BLOB dans une CString ne convient pas. La représentation en mémoire d'une chaîne de caractères hexadécimaux n'est pas la même que tes données brutes. C'est même inefficace au possible, et ça explique pourquoi tu ne vois rien . L'affichage hexadécimal est adapté pour la lecture visuelle de données binaires, mais surtout pas pour les représenter en mémoire. Tu dois récupérer les données brutes telles quelles et les injecter dans CreateBitmap.

    Deuxième point: Je te conseille dans un premier temps de travailler seulement avec les Bitmaps (pas tout de suite les JPG) car c'est un format simple. D'après ce que je lis dans la référence MSDN de CBitmap, le dernier argument est le flux de données de couleurs. Tu ne peux pas injecter ton BLOB directement car le format bitmap contient un header !

    Ce que tu dois faire, selon moi:
    - Extraire les données du header (96,96,1,1) que tu passes actuellement à la main. Tu trouveras aisément de l'aide sur le net, BMP est un format ultra répandu et simpliste.
    - Passer en dernier argument les données amputées du header. Cela revient dans la pratique à incrémenter le pointeur d'un nombre adéquat correspondant à la taille du header. Si tu te vautre quelque part, tu devrais quand même voir des couleurs un peu partout

    Je te laisse te débrouiller pour ça, si tu galères je pourrais t'aider, j'ai déjà manipulé les bitmaps de la sorte. Pour les JPGs, c'est une autre affaire, on verra quand tu auras réussi avec les bitmaps

  5. #5
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Juillet 2012
    Messages : 7
    Par défaut
    Meci à tous pour vos réponses.

    - Koala01 Effectivement je suis daccord avec jblecanard les vectors ne me seront probablement pas d'une grande aide.

    - Bousk : : oui le unsigned char* serait plus approprié , mais disons que cela me simplifier la vie d'utiliser une CString (Enfin visiblement pas ).

    - jblecanard : Oui j'ai commencer avec les bitmaps , je suis assez daccord c'est un format assez simple à utiliser . En effet cela doit venir de mon stockage (CString) qui récupère de l'hexa je vais essayer de récupérer le flux directement dans un stream et le stocker ds un char*. Je t'avoue que pour moi extraire toutes les données d'une image juste avec le header est un coté encore inexploré , mais je vais m'y pencher et je vous tiens au jus pour le résultats.

    Merci à vous.

  6. #6
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Juillet 2012
    Messages : 7
    Par défaut
    Bonjour les amis ,

    Bon en fait je sombre j'essaye des conversion abracabrantesques mais en vain ...

    En fait j'ai oublier de préciser un truc important c'est que je travaille avec des CRecordset , et à la récupération des données à l'aide de la fonction GetFieldValue j'ai le choix à plusieurs prototype de fonction mais seulement 3 type de stockage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    -   GetFieldValue(Short,CString) 
    -   GetFieldValue(Short,CStringW) 
    -   GetFieldValue (Short,ODBCVariant)

    Apres m’être au préalable connecté a la base et avoir ouvert mon recordset , Voici ma fonction d’exécution de la requête SELECT en récupérant champ à champ les données :




    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    /* rs est le recordset ,
        db est un Cdatabase object ,
        vectorArray stocke chaque ligne une à une,
        resultsList stock tous mes vecteurs , soit les lignes retourné par le SELECT   de la base 
    */
    void Database::SelectQuery()
    {
    	static 	int currentColumnNumber = 0;
    	CString tmpString;
    	vector<CString> vectorArray;	
    	CDBVariant varValue;
     
    	// Exécution de la requete
    	try
    	{
    		if (!rs->Open(AFX_DB_USE_DEFAULT_TYPE, this->query)) 
    		{
    			rs->Close();			
    		}
    		else
    		{
    			long numberOfColumns= rs->GetRecordCount();
    			short numberOfRows = rs->GetODBCFieldCount();	
     
    			while (! rs->IsBOF() && !rs->IsEOF()) 
    			{  
    					vectorArray.clear();
     
    					for (int index = 0; index < numberOfRows ; index++) 
    					{
    						try 
    						{	
    							this->rs->GetFieldValue(index,tmpString);
    							// this->rs->GetFieldValue(index,varValue);
    							vectorArray.push_back(tmpString);							
    						}
    						catch (CDBException* Expt) 
    						{
    							AfxMessageBox(Expt->m_strError);
    							Expt->Delete();
    						}
    					}
     
    					this->resultsList.push_back(vectorArray);
     
    					try 
    					{ // champs suivant
    						rs->MoveNext();
    						currentColumnNumber++;
    					}
    					catch( CDBException* Execp) 
    					{
    						AfxMessageBox(Execp->m_strError);
    						Execp->Delete();
    						break;
    					}    		
    				}
    			}
    	}
    	catch (CDBException* pEx) 
    	{     
    		AfxMessageBox("Open Query Failed , Check the query Type. \n"+pEx->m_strError); 
    		pEx->Delete();			
        }   
     
     
    }


    Dans les deux cas de mon GetFieldValue je récupére "quelque chose" mais après deux jour de recherche impossible de bien reconstruire mon image à partir de tout sa......

    Mon champs BLOB dans la base est actuellement à la position index = 9 et contient une image BMP 256 couleurs de 96*96 pixels .

    Malheureusement le net est désert de se côté ou alors je cherche mal.


    Cldt,

Discussions similaires

  1. écrire et lire une base mysql avec visual basic
    Par mitch97 dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 15/02/2007, 23h45
  2. Blob mysql et PHP
    Par manu51_7 dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 12/12/2006, 21h39
  3. Réponses: 19
    Dernier message: 21/01/2006, 13h23
  4. c# et les blob MySQL
    Par marsufunky dans le forum Windows Forms
    Réponses: 3
    Dernier message: 17/11/2005, 10h26
  5. [D 2005]ADO et blob MySql
    Par EFCAugure dans le forum Bases de données
    Réponses: 1
    Dernier message: 24/02/2005, 08h52

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