PureBasic

Forums PureBasic
Nous sommes le Sam 15/Aoû/2020 8:09

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 18 messages ]  Aller à la page 1, 2  Suivante
Auteur Message
 Sujet du message: SQlite et champs BLOB
MessagePosté: Jeu 17/Déc/2015 16:13 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 22/Aoû/2010 15:24
Messages: 6966
Localisation: IDF (Yvelines)
Dans une base de données SQL ont peut stocker des informations de type TEXT ou INTEGER etc ..... mais aussi de type BLOB

Cet type de champ permet de stocker par exemple des images et çà sera le thème de ce sujet.

Prérequis : Connaissance de PureBasic (of course) ainsi que de SQLite ou autres bases de données de type SQL.

Avant de commencer je vous propose cette courte vidéo pour vous montrer le résultat final.
:arrow: https://www.youtube.com/watch?v=eewRoK9W2sc

Pour commencer nous allons créer une base de données très simple permettant de stocker des images.

Cette base de données contiendra la table media ayant cette structure
  - IdMedia de tpe index auto incrémenté (INTEGER PRIMARY KEY)
  - Image de type BLOB
  - Filename de type TEXT

Créer un dossier et enregistrer le code de création de la base de données. Exemple : Medias - Create Database.pb
Code:
EnableExplicit

Global Database.i
Global DatabaseName.s = "assets.sqlite", ReqSql.s

;Création d'un fichier vierge
If CreateFile(Database, DatabaseName)
  CloseFile(Database)
Else
  MessageRequester("Erreur", "Impossible de créer un fichier")
  End
EndIf

;Ouverture et création de la base de données
UseSQLiteDatabase()
If OpenDatabase(Database, DatabaseName, "", "", #PB_Database_SQLite)
 
  ;Préparation de la requête de création de la table des medias
  ReqSql = "CREATE TABLE medias (IdMedia INTEGER PRIMARY KEY, Image BLOB, FileName TEXT)"
   
  ;Exécution de la requete
  DatabaseUpdate(Database, ReqSql) 
  CloseDatabase(Database)
 
  If DatabaseError() = ""
    MessageRequester("Information","Création de la base terminée")
  Else
    MessageRequester("Information","Erreur lors de la création de la table 'medias'" + #CRLF$ + DatabaseError())
  EndIf
Else
  MessageRequester("Erreur","Erreur lors de la création de la base de données" + Chr(13) + DatabaseError() )
EndIf

C'est terminée avec la création de la base de données.

Vous pouvez utiliser SQLite Explorer pour voir la structure de la base.

Passons maintenant à l'exploitation des images ........

_________________

➽ Config PureBasic : Windows 10 Version 64 Bits - DirectX 11 - PB 5.72

➽ Je ne réponds pas aux MP techniques


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Jeu 17/Déc/2015 16:14 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 22/Aoû/2010 15:24
Messages: 6966
Localisation: IDF (Yvelines)
Expoitation des images.

Enregistrer ce code dans le dossier contenant la base de données que nous venons de créer. Exemple: Medias.pb

Ce code permet
  -Sélectionner une image et l'enregistrer dans la base de données.
  -Afficher chacune des images dans une fenêtre.
  -Supprimer une image.

La base de données est ouverte qu'une seule fois lors de l’exécution et fermer quand on quitte l'application.
Code:
; PureBasic 5.70 LTS (x64)

EnableExplicit

Enumeration
  #DataBase
  #ImageFile
  #Buffer
EndEnumeration

Enumeration Window
  #MainForm
EndEnumeration

Enumeration Gadget
  #Selector
EndEnumeration

;Plan du code
Declare Start()                           ;Début
Declare ShowMedia(LastSequence = #False)  ;Affichage d'une ou des images
Declare OnSelectMedia()                   ;Sélection d'une image
Declare OnDeleteMedia()                   ;Suppression d'une image
Declare OnClose()                         ;Fin

Start()

Procedure Start()
  UseJPEGImageDecoder()
  UsePNGImageDecoder()
 
  UseSQLiteDatabase()
  OpenDatabase(#DataBase, "assets.sqlite", "","", #PB_Database_SQLite)
 
  OpenWindow(#MainForm, 0, 0, 800, 600, "SQLite et les champs de type BLOB", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget)     
  ButtonGadget(#Selector, 10, 10, 180, 32, "Sélectionner une image")
 
  ShowMedia() ;Affichage de toutes les images
 
  ;Evenements
  BindEvent(#PB_Event_CloseWindow, @OnClose())
  BindGadgetEvent(#Selector, @OnSelectMedia())
 
  Repeat : WaitWindowEvent(10) : ForEver
EndProcedure

;Affichage de la derniere image ou toutes les images
Procedure ShowMedia(LastSequence = #False)
  Protected Window, IdMedia, ImageEncode.s, FileName.s, *Buffer, Result, Gadget
 
  If LastSequence = #True
    ;Selection de la derniere image
    DatabaseQuery(#DataBase, "SELECT IdMedia, image, filename FROM Medias ORDER BY IdMedia DESC LIMIT 1")
  Else
    ;Selection de toutes les images
    DatabaseQuery(#DataBase, "SELECT IdMedia, image, filename FROM Medias")
  EndIf
 
  ;Affichage du resultat : Chaque image est affichée dans une fenetre
  While NextDatabaseRow(#Database)
    IdMedia     = GetDatabaseLong(#Database, 0)
    ImageEncode = GetDatabaseString(#Database, 1)
    FileName    = GetDatabaseString(#DataBase, 2)
       
    *Buffer = AllocateMemory(Len(ImageEncode)*1.35)
    Result = Base64Decoder(ImageEncode, *Buffer, MemorySize(*Buffer))
   
    If Result
      ReAllocateMemory(*Buffer, Result)
      CatchImage(#Buffer, *Buffer)
      Window = OpenWindow(#PB_Any, 0, 0, ImageWidth(#Buffer), ImageHeight(#Buffer) + 50, FileName, #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_TitleBar)
      ImageGadget(#PB_Any, 0, 0, 0, 0, ImageID(#Buffer))
     
      ;Ajout du bouton de suppression
      ;Mémorisatio de l'index d'enregistrement
      ;Initialisation du Callback de suppression
      Gadget = ButtonGadget(#PB_Any, 10, ImageHeight(#Buffer) + 10, 80, 22, "Supprimer")
      SetGadgetData(Gadget, IdMedia)
      BindGadgetEvent(Gadget, @OnDeleteMedia())
                     
      StickyWindow(Window, #True)
    EndIf
  Wend 
EndProcedure

;Selection d'une image
Procedure OnSelectMedia()
  Protected Pattern.s = "Image Files (*.bmp, *.jpg, *.png)|*.bmp;*.jpg;*.png"
  Protected FileName.s = OpenFileRequester("Sélectionner une image", "", Pattern, 0)
  Protected ImageEncode.s, *Buffer, Result.s
 
  If FileName <> "" 
    ;Lecture et encodage de l'image
    If ReadFile(#ImageFile, FileName)
      *Buffer = AllocateMemory(Lof(#ImageFile))
      ReadData(#ImageFile, *Buffer, Lof(#ImageFile))
      CloseFile(#ImageFile)
     
      ImageEncode = Space(MemorySize(*Buffer)*1.35)
      Result = Base64Encoder(*Buffer, MemorySize(*Buffer))     
      ImageEncode = RTrim(Result)
    EndIf
   
    ;Enregistrement de l'image dans la base de données
    DatabaseUpdate(#DataBase, "INSERT INTO medias (Image, FileName) VALUES ('" + ImageEncode + "', '" + GetFilePart(FileName) + "')")
   
    ;Affichage de la DERNIERE image insérée
    ShowMedia(#True)
  EndIf
EndProcedure

;Suppression d'une image
Procedure OnDeleteMedia()
  Protected IdMedia = GetGadgetData(EventGadget())
 
  DatabaseUpdate(#DataBase, "DELETE FROM Medias WHERE IdMedia=" + IdMedia)
   
  If DatabaseError() <> ""
    MessageRequester("Information", "Erreur lors de la suppression" + #CRLF$ + DatabaseError())
  Else
    CloseWindow(EventWindow())
  EndIf
EndProcedure

Procedure OnClose()
  Protected Window = EventWindow()
  Select Window
    Case #MainForm
      CloseDatabase(#DataBase)
      End
    Default
      CloseWindow(Window)
  EndSelect
EndProcedure

Vous pouvez utiliser SQLite Explorer pour voir la structure et les données de la base.

_________________

➽ Config PureBasic : Windows 10 Version 64 Bits - DirectX 11 - PB 5.72

➽ Je ne réponds pas aux MP techniques


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Jeu 17/Déc/2015 17:19 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 22/Aoû/2010 15:24
Messages: 6966
Localisation: IDF (Yvelines)
Modification du code d'exploitation des images : Il est possible de supprimer une image de la base de données.

_________________

➽ Config PureBasic : Windows 10 Version 64 Bits - DirectX 11 - PB 5.72

➽ Je ne réponds pas aux MP techniques


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Sam 02/Mar/2019 16:22 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 22/Aoû/2010 15:24
Messages: 6966
Localisation: IDF (Yvelines)
Hello. Modification du code d'exploitation des images pour être en conformité avec la version 5.70 de PureBasic.

Ce code a été testé dans un environnement Windows 10 x64 et Mac OS x64.

_________________

➽ Config PureBasic : Windows 10 Version 64 Bits - DirectX 11 - PB 5.72

➽ Je ne réponds pas aux MP techniques


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Sam 02/Mar/2019 16:30 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 14/Oct/2004 19:48
Messages: 1139
Je me demandais pourquoi je n'avais pas eu la notification youtube... Et puis j'ai vu la date du sujet, tout s'explique. ^^
Merci pour cette mise à jour en tout cas. :D

_________________
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 5.45LTS - 32 bits


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Sam 02/Mar/2019 16:41 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 22/Aoû/2010 15:24
Messages: 6966
Localisation: IDF (Yvelines)
Le sujet date un peu et avait besoin d'une bonne mise à jour. Ce qui me désole c'est de ne pas pouvoir lire les bases de données précédentes une fois le code mise à jour.

Suivant les versions de PureBasic, Les fonctions Base64Encoder() et Base64Decoder() ne fonctionnent pas de la même manière. Compiler avec PureBasic 5.70, mon ancienne base de données contenant des images n'est plus exploitable !

_________________

➽ Config PureBasic : Windows 10 Version 64 Bits - DirectX 11 - PB 5.72

➽ Je ne réponds pas aux MP techniques


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Sam 02/Mar/2019 22:09 
Hors ligne

Inscription: Ven 29/Juin/2007 17:50
Messages: 3659
Localisation: Encore ?
Ça donne quoi si tu dématérialises le hachage ?
(pour test j'entends :mrgreen: )


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Sam 02/Mar/2019 23:09 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 22/Aoû/2010 15:24
Messages: 6966
Localisation: IDF (Yvelines)
Ollivier a écrit:
Ça donne quoi si tu dématérialises le hachage ?
(pour test j'entends :mrgreen: )
Je te laisse le soin d'essayer et de nous faire part de ton expérimentation !

_________________

➽ Config PureBasic : Windows 10 Version 64 Bits - DirectX 11 - PB 5.72

➽ Je ne réponds pas aux MP techniques


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Dim 03/Mar/2019 17:59 
Hors ligne

Inscription: Ven 29/Juin/2007 17:50
Messages: 3659
Localisation: Encore ?
"Petit Prince", je ne veux pas te piquer, mais ne me demande pas de faire un sprint pour t'aider. Ça sert à rien : c'est toi qui a les jambes.

Au vu de la simplicité de cette fonction, je suppose que c'est le goulot pour permettre une compatibilité infinie des outils de traitement, pas la sécurité.

Je me trompe?


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Dim 03/Mar/2019 18:30 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 22/Aoû/2010 15:24
Messages: 6966
Localisation: IDF (Yvelines)
Ollivier a écrit:
"Petit Prince", je ne veux pas te piquer, mais ne me demande pas de faire un sprint pour t'aider. Ça sert à rien
Ca sert à rien ? Evite de me poser des questions dans ce cas quand tu peux obtenir des réponses par toi même !

_________________

➽ Config PureBasic : Windows 10 Version 64 Bits - DirectX 11 - PB 5.72

➽ Je ne réponds pas aux MP techniques


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Dim 03/Mar/2019 20:18 
Hors ligne

Inscription: Mer 13/Sep/2017 14:35
Messages: 68
Localisation: Picardie (Somme)
Bonsoir à tous,
:arrow: Si Si ça sert à quelque chose ....Bravo Falsam très bonne :idea:
Et j'ajoute de très bons codes ""Mériteraient" un recyclage de ce genre, sinon ces codes seront perdus à jamais... :wink:
Car derrière il y a l'idée... POUR AVANCER encore et encore :!: Merci Falsam :)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Lun 04/Mar/2019 0:44 
Hors ligne

Inscription: Ven 29/Juin/2007 17:50
Messages: 3659
Localisation: Encore ?
Ne t'égare pas Falsam. Et ne m'invente pas je ne sais quel contexte.

Je pose les questions AVANT que ton travail de mise à jour soit fait. Parce qu'on ne va sûrement pas s'amuser en ASM, APRES avec un gagnant qui crie victoire juste pour la gratuité de l'amusement et toi qui doit te REtaper une autre mise à jour (Si j'ai bien saisi ta problématique).


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Lun 04/Mar/2019 7:18 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1840
Je n'ai pas lu tout le code, mais il n'est plus nécessaire d'encoder les images (Base64Encoder) depuis la v5.40
Le type de données Blob, c'est du binaire, on peut y mettre n'importe quoi directement.
L'encodage64 c'est pour transformer du binaire en texte quand on est sur un système 7 bits.

À partir de la version 5.40 LTS (16 octobre 2015) on a SetDatabaseBlob() qui fera le job tout seul.

D'où effectivement l'intérêt de "moderniser" les tutos

Voir les posts de srod
https://www.purebasic.fr/english/viewto ... 12#p498212

:wink:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Lun 04/Mar/2019 14:12 
Hors ligne

Inscription: Ven 29/Juin/2007 17:50
Messages: 3659
Localisation: Encore ?
Merci Marc56 pour ton aide inlassable et grâcieuse.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SQlite et champs BLOB
MessagePosté: Lun 04/Mar/2019 15:11 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1840
La procédure OnSelectMedia() peut donc être simplifiée si on a PB >= 5.40 LTS
Code:
;Selection d'une image
Procedure OnSelectMedia()
  Protected Pattern.s = "Image Files (*.bmp, *.jpg, *.png)|*.bmp;*.jpg;*.png"
  Protected FileName.s = OpenFileRequester("Sélectionner une image", "", Pattern, 0)
  Protected *Buffer
 
  If FileName <> "" 
    ;Lecture et encodage de l'image
    If ReadFile(#ImageFile, FileName)
      *Buffer = AllocateMemory(Lof(#ImageFile))
      ReadData(#ImageFile, *Buffer, Lof(#ImageFile))
      CloseFile(#ImageFile)

      SetDatabaseBlob   (#DataBase, 0, *Buffer, MemorySize(*Buffer))
      SetDatabaseString (#DataBase, 1, GetFilePart(FileName))
    EndIf
    DatabaseUpdate(#DataBase, "INSERT INTO medias (Image, FileName) VALUES (?, ?)")
   
    ;Affichage de la DERNIERE image insérée
    ;ShowMedia(#True)
  EndIf
EndProcedure

On peut vérifier que l'image est bien stockée dans la base avec par exemple SQLiteStudio qui affiche le champs image (double-clic que le champ image, puis onglet 3)

:arrow: Reste à modifier ShowMedia() pour que l'exemple soit complet.

C'est quand même bien ces variables de liaison :) (requêtes préparées / Prepared statement)

:wink:


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 18 messages ]  Aller à la page 1, 2  Suivante

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 18 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  
cron

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye