Matware456
Messages postés19Date d'inscriptionjeudi 23 novembre 2006StatutMembreDernière intervention27 août 2009
-
21 juin 2009 à 15:32
Matware456
Messages postés19Date d'inscriptionjeudi 23 novembre 2006StatutMembreDernière intervention27 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 ! :)
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 21 juin 2009 à 19:10
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.
Matware456
Messages postés19Date d'inscriptionjeudi 23 novembre 2006StatutMembreDernière intervention27 août 2009 21 juin 2009 à 18:13
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...).
Matware456
Messages postés19Date d'inscriptionjeudi 23 novembre 2006StatutMembreDernière intervention27 août 2009 21 juin 2009 à 19:47
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. =/
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 21 juin 2009 à 20:06
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)
Matware456
Messages postés19Date d'inscriptionjeudi 23 novembre 2006StatutMembreDernière intervention27 août 2009 21 juin 2009 à 20:12
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é.
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 21 juin 2009 à 20:33
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.
Nicolas___
Messages postés992Date d'inscriptionjeudi 2 novembre 2000StatutMembreDernière intervention24 avril 20131 21 juin 2009 à 20:38
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)
Matware456
Messages postés19Date d'inscriptionjeudi 23 novembre 2006StatutMembreDernière intervention27 août 2009 21 juin 2009 à 21:56
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. ^^
Matware456
Messages postés19Date d'inscriptionjeudi 23 novembre 2006StatutMembreDernière intervention27 août 2009 22 juin 2009 à 20:57
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.