Mettre un TBitmap en mémoire [Résolu]

Messages postés
19
Date d'inscription
jeudi 23 novembre 2006
Statut
Membre
Dernière intervention
27 août 2009
- - Dernière réponse : Matware456
Messages postés
19
Date d'inscription
jeudi 23 novembre 2006
Statut
Membre
Dernière intervention
27 août 2009
- 22 juin 2009 à 20:57
Bonjour,

Comme le titre l'indique j'aimerais placer un TBitmap en mémoire, c'est à dire le placer entièrement dans la RAM pour pouvoir le réutiliser dans un autre programme, j'ai bien cherché et je n'ai trouvé que quelques solutions : avec le handle du bitmap (ne marche pas, je croit qu'il est détruit dès que l'on ferme le programme), avec un TMemoryStream (idem) et avec un CreateFileMapping (doit marcher mais je suis un peu perdu dans son utilisation...).

L'idée serait de faire 3 fonctions dans une DLL :
ShareDC(window_handle:HWND):Integer; (récupération du DC déjà programmé mais impossible de mettre le bitmap créé en mémoire, valeur de retour : le handle de l'image en mémoire)
GetPixel(x:integer,y:integer,image_handle:integer):COLORREF; (retourne la couleur du pixel grâce à un ScanLine)
Free(image_handle:integer); (libére l'image de la mémoire)

J'en profite aussi pour vous demander si ces fonctions seront rapide car si elles ne le sont pas, ce n'est pas la peine...
Merci pour votre future aide précieuse ! :)
Afficher la suite 

15 réponses

Meilleure réponse
Messages postés
3869
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
5
3
Merci
Tu peux mettre dans le fichier paginé de Windows mais j'ai peur qu'il faille établir une connexion simultanée pour effectuer le transfert inter-processus (il faut qu'à un moment, les 2 processus aient le même accès au fichier, car si aucun processus n'a plus accès au fichier paginé ce dernier est détruit.

Cordialement, Bacterius !

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 123 internautes nous ont dit merci ce mois-ci

Commenter la réponse de Bacterius
Messages postés
3869
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
5
0
Merci
Tu peux vraiment pas le mettre dans un fichier temporaire qui durerait le temps que Windows dure ?

Cordialement, Bacterius !
Commenter la réponse de Bacterius
Messages postés
19
Date d'inscription
jeudi 23 novembre 2006
Statut
Membre
Dernière intervention
27 août 2009
0
Merci
Bah malheureusement non, j'ai besoin de ces fonctions pour en remplacer une autre qui est très lente (dans un autre langage) et j'aimerais ne pas passer par le disque (trop lent...).

Merci de ton aide !
matware456
Commenter la réponse de Matware456
Messages postés
19
Date d'inscription
jeudi 23 novembre 2006
Statut
Membre
Dernière intervention
27 août 2009
0
Merci
Mmhh, pas pratique... N'y-aurait-il pas d'autre solution ?
Sinon pour le même accès au fichier, c'est-à-dire ?
Commenter la réponse de Matware456
Messages postés
3869
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
5
0
Merci
Tu peux lire mon tutoriel sur les pointeurs, il y a un chapitre dédié aux fichiers paginés, tu pourrais y apprendre des trucs.

http://www.delphifr.com/tutoriaux/POINTEURS-DELPHI_962.aspx

Après je t'explique si tu as toujours des questions.

Cordialement, Bacterius !
Commenter la réponse de Bacterius
Messages postés
19
Date d'inscription
jeudi 23 novembre 2006
Statut
Membre
Dernière intervention
27 août 2009
0
Merci
Déjà lu... (il est super bien fait ^^)
Mais tu ne parles pas de la suppression de la ressource quand elle n'est plus utilisée, peux-tu m'en dire plus ?

Et sinon pourquoi ne pas tout simplement utilisé le handle d'un TBitmap sans le détruire, ça marcherait peut-être... Mais mes essais n'ont pas été concluant. =/
Commenter la réponse de Matware456
Messages postés
3869
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
5
0
Merci
Alors,
Windows a introduit la notion de fichier paginé ... blablabla ... seulement ce fichier n'existe que tant qu'un processus s'en sert. Il existe en fait un compteur de référence sur un objet quelconque (ici le fichier paginé). Lorsqu'il est créé, ce compteur passe à 1. Lorsqu'un processus essaye de créer (ou tente d'ouvrir) le même fichier, le compteur s'incrémente. Lorsqu'un processus libère (ou ferme) le même fichier, le compteur se décrémente. Lorsque le compteur passe à 0, l'objet (fichier paginé) est détruit. C'est pourquoi il faut toujours garder un compteur > 0. Donc, il faudrait faire comme ça :

Processus 1 crée le fichier (Compteur à 1)
Processus 2 ouvre le fichier (Compteur à 2)
Processus 1 ferme le fichier (Compteur à 1)
Processus 2 fait des trucs sur le fichier
Processus 2 libère le fichier (Compteur à 0)

Cordialement, Bacterius !
Commenter la réponse de Bacterius
Messages postés
19
Date d'inscription
jeudi 23 novembre 2006
Statut
Membre
Dernière intervention
27 août 2009
0
Merci
Ah ok je croyais que l'espérance de vie du fichiers mappé était limitée. ^^

Moi ça serait plutôt ça :
Processus 1 créé le fichier mappé via une DLL et renvoi son identifiant.
Processus 1 traite des données (sans le fichier mappé).
Processus 1 rentre dans une boucle et analyse les pixels de l'image mappé (grâce à la fonction expliquée dans mon premier message).
Processus 1 libère le fichier mappé.

Merci de ton aide encore une fois ! :)
Matware456
Commenter la réponse de Matware456
Messages postés
3869
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
5
0
Merci
"Ah ok je croyais que l'espérance de vie du fichiers mappé était limitée."

C'est ce que je viens d'expliquer, tu avais raison donc. N'y-a-t-il pas un problème dans ta phrase ?

Cordialement, Bacterius !
Commenter la réponse de Bacterius
Messages postés
3869
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
5
0
Merci
Sinon je ne suis pas d'accord pour le GetPixel : tu devrais l'appeller pour chaque pixel : très mauvais !
Essaye plutôt comme ça :

GetPBitmap: Pointer;

Qui renvoie un pointeur sur le premier pixel du bitmap (premier pixel de la dernière ligne du bitmap). Après, tu parcours le bitmap en incrémentant le pointeur.

Cordialement, Bacterius !
Commenter la réponse de Bacterius
Messages postés
1039
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
2
0
Merci
si tu veux partager ton bitmap entre <> application , tu peux tjs le faire passer dans le presse papier en utilisant

SaveToClipboardFormat

Crée une copie locale du bitmap au format du Presse-papiers.

Syntaxe Delphi :

procedure SaveToClipboardFormat(var AFormat: Word; var AData: THandle; var APalette: HPALETTE); override;

Syntaxe C++ :

virtual void __fastcall SaveToClipboardFormat(Word &AFormat, int &AData, HPALETTE &APalette);

Description

Utilisez la méthode SaveToClipboardFormat pour copier le bitmap dans un des formats du Presse-papiers. La palette du bitmap est renvoyée comme valeur du paramètre APalette, le format comme valeur du paramètre AFormat et un handle aux données comme valeur du paramètre AData. Avant de pouvoir enregistrer le bitmap, une application doit avoir recensé le format utilisé par l'objet TBitmap en appelant la méthode RegisterClipboardFormat.

De cette facon, tu seras le récupérer dans une autre application et cela assez facilement ...
(il existe plusieurs sources sur le site qui parle de ce sujet)

Nico
Commenter la réponse de Nicolas___
Messages postés
1039
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
2
0
Merci
bien sur , le bitmap existe encore dans le presse papier, même si l'application est fermée (presque sur ^^ )
Commenter la réponse de Nicolas___
Messages postés
3869
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
5
0
Merci
Jusqu'à ce qu'une autre application réutilise le presse-papiers ^^'

Cordialement, Bacterius !
Commenter la réponse de Bacterius
Messages postés
19
Date d'inscription
jeudi 23 novembre 2006
Statut
Membre
Dernière intervention
27 août 2009
0
Merci
Excuse-moi, je ne suis pas clair : je parlait limité dans le temps...
Je vais essayer avec les fichiers mappés si tu as une solution plus simple ou plus rapide, n'hésite pas. ^^

Merci pour ton aide !
@++
Matware456
Commenter la réponse de Matware456
Messages postés
19
Date d'inscription
jeudi 23 novembre 2006
Statut
Membre
Dernière intervention
27 août 2009
0
Merci
Oups, je n'avais pas vu la deuxième page. -_-"
Donc pour le presse-papier, je ne peux pas l'utiliser car je compte faire une DLL et j'aimerais qu'elle soit compatible avec toutes les applications, mêmes celles qui utilisent le presse-papier, donc ça m'est malheureusement impossible.

Ensuite pour le GetPixel, c'est uniquement le nom de la fonction, j'ai prévu d'utiliser des ScanLines. =)

Pis nouvelle erreur :
procedure Tprint_dc.memoryClick(Sender: TObject);
var
hMapFile : THandle;
begin
image.Picture := nil;
hMapFile := OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,PChar(handle.Text));
CopyMemory(Pointer(image),MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,0,0,320*240*4),320*240*4);
image.Refresh;
end;

Ça me fait une EAccessViolation... Je précise que mon image est en 320 * 240 en 24bits.

Merci de votre aide, Matware456.
Commenter la réponse de Matware456