PROCEDURE POUR INTEGRER UN BLOB DANS UNE BASE DE DONNÉES PARADOX

f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 - 5 août 2006 à 04:47
cs_massi Messages postés 28 Date d'inscription mardi 18 mars 2003 Statut Membre Dernière intervention 31 janvier 2013 - 5 janv. 2013 à 14:32
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/38930-procedure-pour-integrer-un-blob-dans-une-base-de-donnees-paradox

cs_massi Messages postés 28 Date d'inscription mardi 18 mars 2003 Statut Membre Dernière intervention 31 janvier 2013
5 janv. 2013 à 14:32
bonjour
y a pas possibilité de faire simple svp
moi ayant une table accesss 2007, je n'arrive pas à adapter ce code comment faire svp simplement.
merci
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
19 janv. 2007 à 00:45
désolé pour ce retard mais j'ai pas eu le temps ces derniers jours

Alors pour tes question une seul réponse:
la bibliothèque JVCL gratuite elle comprend deux composant un pour afficher les image sous format Jpeg ( et autres fromat d'ailleurs) et un composant DBJVIMAge qui agit exactement comme DBimage et il accepte les Jpeg tu trouvera la derniere version stable de cette bibliothèque (600 composants visuels et non-visuels) à l'adresse suivante:
http://sourceforge.net/project/showfiles.php?group_id=45786
smail21 Messages postés 12 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 1 janvier 2007
1 janv. 2007 à 16:31
Merci pour on aide!
alors pour l'erreur que j'avais, il falait juste faire l'execution de l'executable en fermant delphi
autre chose pour le blob, j'ai su qu'il falait faire le type Binary ce qui m'avait réglé la moitié du probleme
maintenant je cherche le composants qui ouvre des images Jpg!
j'ai pas encore trouvé!

autres questions: si après ça marche et que j'enregstre des images au format Jpg, est-ce que un DBimage poura me les afficher comme les bmp déja enregistré? ou dois-je utiliser uen autre fonction de lecture pour les afficher?
merci
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
1 janv. 2007 à 12:54
pour enregistrer l'image dans la table voici le code
//ceici est la fonction de remplissage amélioté par F0xi
function WriteBlobFile(Table : Ttable; const Field, FileName : string) : boolean;
var blob,fs : Tstream;
begin
table.edit;
result := false;
if (not FileExists(FileName)) or (not Assigned(Table)) then exit;
blob := nil;
fs := nil;
try
blob := table.CreateBlobStream(table.FieldByName(Field),bmWrite);
blob.Seek(0,soFromBeginning);
try
fs := Tfilestream.Create(FileName, fmOpenRead or fmShareDenyWrite);
blob.CopyFrom(fs, fs.size);
result := true;
finally
fs.Free;
end;
finally
blob.Free;
table.Refresh;
end;
end;
/// ceci est la procedure à appeler lorsqu'on appui sur le bouton choix d'image!
procedure TAj_ele.OKClick(Sender: TObject);
Var fn:string;
begin
if Opd1.execute then
begin
fn:=opd1.FileName;
if not WriteBlobFile(eleve, 'ph', fn) then
MessageDlg('Erreur d''ecriture du fichier dans la table...',mtWarning,[mbOk],0);
end;
image1.Picture.LoadFromFile(opd1.FileName);
end;
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
1 janv. 2007 à 12:36
ah voila l'erreur!
utilise la procedure tel qu'elle est mais il faut definir le champ 'Image ' en tant que BLOB (binary) et non un Graphic
car pour Delphi si vou declarer le champs en tant que Graphic il va verifier que c'est une image BMP ou Ico
part contre en le déclarant sous format de (BLOB) vous pouvez mettre ce que vous voulez dedans( avi,mpeg jpeg swf ...)
l'astuce ça sera dans la lecture il vous faudra un conteneur qui permet la lecture des gif et des Jpeg vous trouverer un composant Image qui permet ceci dans la bibléothéque de JVCL
PS:le nom de champ doit être passé à la procedure en String.
j'espére que ça fonctio,nera pour vous en attendant bonne année à tous les participant! a+
smail21 Messages postés 12 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 1 janvier 2007
27 déc. 2006 à 15:37
@Blatour : ça ne marche pas c'est toujours le même message
quant à la procedure de Foxi, il me dit: erreur d'écriture dans le flux :(
smail21 Messages postés 12 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 1 janvier 2007
27 déc. 2006 à 14:05
je viens d'utiliser la Fonction améliorée de Foxi, elle me permet d'ouvrir un dialogue et de choisir l'image mais en cliquant sur ouvrir, j'ai un message d'erreur d'écriture dans le flux
blatour Messages postés 26 Date d'inscription mardi 6 mai 2003 Statut Membre Dernière intervention 11 décembre 2006
27 déc. 2006 à 13:57
Essaies ça :

procedure TForm1.remplirblob( var table:Ttable;opd:TOpenPictureDialog;champ:string);
//champ designe le champs de la table alloué au BLOB
begin
TBlobField(Table.FieldByName(Champ)).LoadFromFile(opd.FileName);
end;

Par contre, mettre var pour la table, à mon avis, ça ne sert à rien.

Crd.
smail21 Messages postés 12 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 1 janvier 2007
27 déc. 2006 à 13:52
j'ai remplacé l'appel de la procédure

remplirblob(MaTable,opd1,Image);


par

remplirblob(MaTable,opd1,'Image');

puisque le champ est délcaré dans la procédure d etype String

ça s'execute mais dès que je clique sur le bouton OK, j'ai un message d'erreur qui me dit impossible d'ouvrir un fichier, alors que je n'ai que cliqué sur le bouton!
smail21 Messages postés 12 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 1 janvier 2007
27 déc. 2006 à 13:35
est-ce que le problème n'est pas dans le type du champs? car il est déclaré String et moi mon champs image est de type Graphic!?

donc j'ai deux problèmes :
1- l'erreur du point attendu mais ) trouvé
2- l'enregistrement des images de types jpg
smail21 Messages postés 12 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 1 janvier 2007
27 déc. 2006 à 13:32
voici tout le code :

procedure TForm1.remplirblob( var table:Ttable;opd:TOpenPictureDialog;champ:string);
//champ designe le champs de la table alloué au BLOB
var blob,fs:Tstream;
begin
blob:=table.CreateBlobStream(table.FieldByName(champ),bmWrite);
try
blob.Seek(0,soFromBeginning);
fs:= Tfilestream.Create(opd.FileName,fmOpenRead or fmShareDenyWrite);
try
blob.CopyFrom(fs, fs.size);
finally
fs.Free;
end;
finally
blob.Free;
end;
end;

procedure TForm1.OKClick(Sender: TObject);
begin
remplirblob(MaTable,opd1,Image);
end;
blatour Messages postés 26 Date d'inscription mardi 6 mai 2003 Statut Membre Dernière intervention 11 décembre 2006
27 déc. 2006 à 13:19
Salut, peux tu nous faire aussi passer ta procedure "RemplirBlob" stp ?

Crd.
smail21 Messages postés 12 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 1 janvier 2007
27 déc. 2006 à 12:13
voic le code que j'ai:

procedure TForm1.OKClick(Sender: TObject);
begin
remplirblob(MaTable,opd1,Image);
end;

en executant il m'affiche l'erreur suivante :

[Erreur] image.pas(56): '.' attendu(e) mais ')' trouvé(e)

je n'ai pas trouvé où est l'erreur!
smail21 Messages postés 12 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 1 janvier 2007
27 déc. 2006 à 11:35
merci beaucoup GHASSENUS!

ça marche très bien sauf qu'il n'accepte que des image BMP ou icone, mais il ne me donne pas la main pour enregistrer des GIF ou JPeg car mes utilisateurs peuvent insérer n'importe quel type d'image!
comment faire?
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
26 déc. 2006 à 20:43
Alors Smail21 ce code est géneral tu peux l'utiliser avec n'importe qu'elle table sans paramétrage spécifique
voici un exemple
on utilise une table paradox dont le nom est "Ma_Table";
le champ Blob a pour nom "img" sur une feuille j'utilise un bouton "Ok" pour introduire une image dans la table et un "Opd1" comme OpenDialog.

voici la procedure pour enregistrer l'image dans la table

procedure TForm1.OkClick(Sender: TObject);
begin
remplir_blob( Ma_Table,opd1,img);
end;
est le tour est joué
;)
de m^me pour la lecture du champ Blob;
smail21 Messages postés 12 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 1 janvier 2007
23 déc. 2006 à 13:26
je m'excuses mais je me perd dans vos codes sources!
je n'arrive pas à les essayer! car je ne sai spas comment dois-je paramétrer mes composants à utiliser.
mon problème est de pouvoir enregistrer des images (aux formats divers) dans une table (champs de type Bolb) donc je vous demande de m'aider et em dire comment dois-je faire

car pour le format BMP ça ne pose pas de probleme j'utilise une table et un OpenDialog.
j'attends vos réponses
merci
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
11 août 2006 à 18:17
je me panche sur le sujet mais une aide sera la bien venue merci
je voudrais ajouter la fonction LoadFromstream à un compsant Activix de Flashpalyer
blatour Messages postés 26 Date d'inscription mardi 6 mai 2003 Statut Membre Dernière intervention 11 décembre 2006
11 août 2006 à 10:21
Bonjour,

Je n'utilise pas ces composants. Je suppose que ça doit être possible.
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
10 août 2006 à 22:40
oui c'est ce que je fait
iln'yas pas de loadfromstrem
peut on transformer ces composant pour ajouter cette propriétés
je sais que c'est un peu delicat mais je crois que c'est fesable
blatour Messages postés 26 Date d'inscription mardi 6 mai 2003 Statut Membre Dernière intervention 11 décembre 2006
8 août 2006 à 13:53
Il faut regarder au niveau de ces contrôles s'ils disposent d'une propriété "LoadFromStream". Si ce n'est pas le cas, il faut passer par l'enregistrement sur le disque dur.

Mais après lecture du fichier par le composant, il est tout à fait possible de supprimer le fichier du disque dur après utilisation. Ce qui n'est pas génant en soit.
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
8 août 2006 à 13:30
Ok c'est trés bien ça mais puis je par exemple affecter un Stram directement à un Activix (Media Player ou flash) par exemple pour lecture moi ce que je fait c'est sauvgarder stream ds un fichier puis je l'appel par les propriétés du contrôle en question mais ceci me parit peux orthodoxe ;)
blatour Messages postés 26 Date d'inscription mardi 6 mai 2003 Statut Membre Dernière intervention 11 décembre 2006
8 août 2006 à 12:53
De rien.

En plus avec le TMemoryStream, tu peux aussi tester le format du fichier comme je l'ai montré (ou par une autre méthode) et après enregistrer directement le contenu dans un fichier avec la bonne extension si nécessaire :

// Test du contenu
lStr.Position := 0; ' Il faut toujours remettre la position du curseur au début du Stream
lStr.SaveToFile(NomFichier + Extension);

Et le tour est joué.
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
8 août 2006 à 12:37
@Baltour
merci ça m'aide beaucoup ton travaille à+
blatour Messages postés 26 Date d'inscription mardi 6 mai 2003 Statut Membre Dernière intervention 11 décembre 2006
8 août 2006 à 10:46
Salut DelphiProg,

Oui mais dans mon cas, je n'avais à faire qu'à ces 3 types de fichiers ;-).
C'est juste un exemple sortant d'une de mes sources.

Mais pour ceux que ça intéresse,le format BitMap commence par les 2 caractères suivants : 'BM'.
Codage héxadécimal : 42 4d

Bon codage à tous.
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
8 août 2006 à 10:42
Ok merci je l'ai considerer comme un stream
je n'arrive pas encore à maitriser ces streams
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
7 août 2006 à 22:33
@blatour:
C'est pas mal et c'est surement une des voies à suivre sauf en ce qui concerne le cas par défaut, toujours un peu scabreux. Quid des png et autres formats ?
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
7 août 2006 à 22:16
@ghassenus :
Pourquoi vouloir libérer TF alors qu'il pointe sur un champ existant ? Ici, il ne s'agit pas de libérer la mémoire par un objet créé dans le corps de la procédure ReadBlobField mais d'utiliser une référence existante (Table.FieldbyName(Field) as TBlobField). Donc point de libération, même conditionnelle :)
blatour Messages postés 26 Date d'inscription mardi 6 mai 2003 Statut Membre Dernière intervention 11 décembre 2006
7 août 2006 à 20:00
Re bonjour,

Pour ceux que ça intéresse voici une fonction que j'ai écrite pour tester le format de certains fichier (Gif, Jpeg et BitMap) et on l'affecte à un TImage :

Appelle de la fonction :

LitPhoto(TBlobField(NomTable.FieldByName('NomChamp')), ComposantTImage);
Exemple :
LitPhoto(TBlobField(qryProduit.FieldByName('PRD_PHOTO')), formProduit.imgPhoto);

La fonction :

Procedure LitPhoto(Champ : TBlobField ; var Image : TImage);
var
lStr : TMemoryStream;
lTete : array[0..6] Of Char;
lGif : TGifImage;
lJpg : TJPEGImage;
lImg : tBitMap;
begin
If Not Champ.IsNull then ' On test si le champ est nul
begin
lStr := TMemoryStream.Create; ' On créé un MemoryStream
Try
Champ.SaveToStream(lSTr); ' On affecte le contenu du champ dans le MemoryStream
lStr.Position := 0;
lStr.Read(lTete[0], Length(lTete)); ' On lit les 6 premiers caractères que l'on place dans la variable lTete
lStr.Position := 0;
If (Ord(lTete[0]) = 71) And (Ord(lTete[1]) = 73)
And (Ord(lTete[2]) = 70) then ' Test pour savoir si c'est un Gif
begin
lGif := TGIFImage.Create;
Try
lGif.LoadFromStream(lStr);
Image.Picture.Assign(lGif);
Finally
lGif.Free;
end;
end
else If (Ord(lTete[0]) = 255) And (Ord(lTete[1]) = 216)
And (Ord(lTete[2]) = 255) then ' Test pour savoir si c'est un jpeg
begin
lJpg := TJPEGImage.Create;
Try
lJpg.LoadFromStream(lStr);
Image.Picture.Assign(lJpg);
Finally
lJpg.Free;
end;
end
else ' Sinon c'est un bitmap
begin
lImg := TBitmap.Create;
Try
lImg.LoadFromStream(lStr);
Image.Picture.Assign(lImg);
Finally
lImg.Free;
end;
end;
Finally
lStr.Free;
end;
end
else
Image.Picture.Graphic := Nil;
end;

Et voilà. En espérant que ça vous aide.
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
7 août 2006 à 19:38
Voici la fonction finale: mais j'ai un prb avec le FT.Free je ne comprend pas pourquoi alors de l'aide SVP

function ReadBlobField(Table:TTable;const Field,FileName:String ):String;
var
TF:TBlobField;
Begin
try
TF:=Table.FieldbyName(Field) as TBlobField;
TF.SaveToFile(ExtraCtFilePatH(Application.ExeName)+ FileName);
result:=ExtraCtFilePatH(Application.ExeName)+ fileName;
finally
//TF.Free;
end;
End;

ça marche trés bien sans le Free sinon ça bloque
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
7 août 2006 à 19:06
OK voila mon Ideé en claire ( J'utulise un Fichier flash mais rien n'empêche d'utiliser tout autre type de Fichier)
procedure TForm2.Button1Click(Sender: TObject);
Var TF:TBlobField;
begin
  TF:=Table1.FieldByName('Ani') as TBlobField ;
  TF.SaveToFile('.\SF_Temp.swf');
  TE.free;
  SF1.LoadMovie(0,ExtraCtFilePatH(Application.ExeName)+'SF_Temp.swf');
 SF1.Play;
end;
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
7 août 2006 à 17:27
Ok moi aussi je me panche Mnt sur la lecture d'un champs binaire ma premiére idée est d'utliser un SaveTo puis un LoadFrom car je ne maitrise pas encore la technique du Streaming alors dés que j'arrive à quelque chose je vous donne de mes nouvelle merci encore pour vos commentaires!
labchara Messages postés 8 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 7 août 2006
7 août 2006 à 13:17
Merci pour ce petit code , en effet la partie champs memo est peu developpé sur les livres et les sites de delphi, d'ailleurspour ma part je cherche toujours une methode simple pour lire le cotenu des champs binaire avec bdd sql.
blatour Messages postés 26 Date d'inscription mardi 6 mai 2003 Statut Membre Dernière intervention 11 décembre 2006
7 août 2006 à 10:55
Bonjour,
Pourquoi ne pas faire :

TBlobField(table.FieldByName(Field)).LoadFromFile(FileName);

ou si vous utilisez un Stream :

TBlobField(table.FieldByName(Field)).LoadFromStream(LeStream);

Sinon merci à toutes les personnes intervenants sur ce site pour la qualité de leur post.
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
6 août 2006 à 22:58
Ce type de code est souvvent demandé dans le forum et c'est bien de l'avoir publié.
Je rejoins tout à fait Foxi pour ses remarques constructives (sauf peut-être pour l'affectation à Nil des deux pointeurs blob et fs qui ne sont pas d'une grande utilité ici).

Je sens que tu vas devoir te coller à l'opération inverse, c'est à dire la lecture. En effet, écrire dans un champ blob est une opération assez facile. En revanche, la lecture est plus délicate quand on peut y trouver des contenus de nature différentes : images, sons, etc.
Alors, bon courage et n'oublies pas que toutes les images ne sont pas des jpeg !
cs_ghassenus Messages postés 33 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 27 avril 2007
5 août 2006 à 10:27
merci c'est vrai que c'est plus interessant ainsi
on est la pour apprendre !
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
5 août 2006 à 04:47
salut, interressant pour les debutants, toute fois elle gagnerais en utilitée declarée comme suis :



function WriteBlobFile(Table : Ttable; const Field, FileName : string) : boolean;
var blob,fs : Tstream;
begin
result := false;
if (not FileExists(FileName)) or (not Assigned(Table)) then exit;
blob := nil;
fs := nil;
try
blob := table.CreateBlobStream(table.FieldByName(Field),bmWrite);
blob.Seek(0,soFromBeginning);
try
fs := Tfilestream.Create(FileName, fmOpenRead or fmShareDenyWrite);
blob.CopyFrom(fs, fs.size);
result := true;
finally
fs.Free;
end;
finally
blob.Free;
end;
end;


comme ça peu importe l'utilisation d'un OpenDialog ou autre ...
il suffit juste d'indiquer le nom de fichier.
le retour boolean permet de savoir si le fichier a bien été inscrit dans la table.
en cas de fichier inexistant ou d'objet TTable non alloué on ne doit pas aller plus loin.
les objets ne se declarer pas en VAR ... mais sans parametres.
les autres arguments peuvent etre declarer CONST c'est mieux.


exemple d'utilisation :

if OpenDialog1.execute then
if not WriteBlobFile(MaTable, 'Image', OpenDialog1.FileName) then
MessageDlg('Erreur d''ecriture du fichier dans la table...',mtWarning,[mbOk],0);