Accueil > Forum > > > > Question sur l'utilisation des TBitmap dans les fonctions...
Question sur l'utilisation des TBitmap dans les fonctions...
lundi 23 octobre 2006 à 13:08:44 |
Question sur l'utilisation des TBitmap dans les fonctions...

cerber943
|
Bonjour, J'ai créé quelques fonctions qui retournent des TBitmap. Je rencontre actuellement une augmentation de l'espace mémoire alloué à mon programme au fil de l'exécution de ces fonctions. Je suppose donc que je ne dois pas libérer les images correctement. A chaque fin de procédure mes images intermédiaires sont libérées par if Assigned(mon_img) then mon_img.Free;
Je me posais la questions si mes images étaient copiées ou transmises par références dans ce genre de situation : function get_img() : TBitmap; begin result:=TBitmap.Create; result.width:=10; result.height:=10; [...] bref on alloue cette image [...] end;
procedure test_img (img : TBitmap) : Boolean; begin // fait quelque chose avec cette image end;
Et dans ma fonction main : if test_img(get_img) then ....
Je me demande si je peux écrire
if test_img(get_img) then ....
ou si je dois écrire : tmp_img:=get_img; if test_img(tmpImg) then .... if Assigned(tmp_img) then tmp_img.Free;
De même (mais je pense avoir la réponse), j'ai un doute quand à l'utilisation de boucles pour parcourir les pixels des Canvas des Bitmap : doit-je itérer de 0 à Height-1 (ce que je pense) ou de 0 à Height ? Je me pose la question car itérer de 0 à Height ne semble pas gérer de message d'erreur à l'exécution, mais un résultat incertain. J'espère avoir été assez clair et je vous remercie par avance de votre aide
|
|
lundi 23 octobre 2006 à 23:54:39 |
Re : Question sur l'utilisation des TBitmap dans les fonctions...

f0xi
|
Réponse acceptée !
ok je vais essayer de t'eclairer : pour créer un bitmap par une methode mieux vaut prendre une procedure ou une fonction a retour booleen : function CreateBitmap(BMP : TBitmap; const AWidth, AHeight : integer; const APixelFormat : TPixelFormat = pf32bit) : boolean; begin result := false; if not Assigned(BMP) then begin BMP := TBitmap.Create; BMP.Width := AWidth; BMP.Height:= AHeight; BMP.PixelFormat := APixelFormat; result := true; end; end;
>> CreateBitmap(MonBitmap1,10,10); // crée une image 32 bits par defaut >> CreateBitmap(MonBitmap2,10,10,pf24bit); // force une image 24 bits
function FreeBitmap(BMP : TBitmap) : boolean; begin result := false; if Assigned(BMP) then begin FreeAndNil(BMP); result := true; end; end;
>> FreeBitmap(MonBitmap1); // libere et remet a nil la variable MonBitmap1 >> FreeBitmap(MonBitmap2); // libere et remet a nil la variable MonBitmap1
ensuite pour acceder aux pixels d'un bitmap le mieux c'est ScanLine (canvas.pixel est trés long d'accés) : const MAXWidth = 4096;
type TPixel24bit = record R,G,B : byte; end;
TPixel32bit = record R,G,B,A : byte; end; pSLPixel24 = ^TSLPixel24; pSLPixel32 = ^TSLPixel32; TSLPixel24 = array[0..MAXWidth] of TPixel24bit; TSLPixel32 = array[0..MAXWidth] of TPixel32bit;
function GetPixelRGB24(BMP : TBitmap; const X,Y : integer; out Pixel : TPixel24bit) : boolean; var pPL : pSLPixel24; begin result := false; if ((X >= 0) and (X <= BMP.Width-1)) and ((Y >= 0) and (Y <= BMP.Height-1) then begin pPL := BMP.ScanLine[y]; Pixel := pPL[X]; result := true; end; end;
function GetPixelRGB32(BMP : TBitmap; const X,Y : integer; out Pixel : TPixel32bit) : boolean; var pPL : pSLPixel32; begin result := false; if ((X >= 0) and (X <= BMP.Width-1)) and ((Y >= 0) and (Y <= BMP.Height-1) then begin pPL := BMP.ScanLine[y]; Pixel := pPL[X]; result := true; end; end; function SetPixelRGB24(BMP : TBitmap; const X,Y : integer; const Pixel : TPixel24bit) : boolean; var pPL : pSLPixel24; begin result := false; if ((X >= 0) and (X <= BMP.Width-1)) and ((Y >= 0) and (Y <= BMP.Height-1) then begin pPL := BMP.ScanLine[y]; pPL[X] := Pixel; result := true; end; end;
function SetPixelRGB32(BMP : TBitmap; const X,Y : integer; const Pixel : TPixel32bit) : boolean; var pPL : pSLPixel32; begin result := false; if ((X >= 0) and (X <= BMP.Width-1)) and ((Y >= 0) and (Y <= BMP.Height-1) then begin pPL := BMP.ScanLine[y]; pPL[X] := Pixel; result := true; end; end;
et un exemple de la boucle type pour utiliser ScanLine, pour les algorythmes d'images complexe ou non : { athlon 2700+ @ 2Ghz / bitmap 640x480 = 0..7ms } procedure NegativizeScanline(BMP : TBitmap); var pPL : pSLPixel32; X,Y : integer; begin BMP.PixelFormat := pf32bit; for Y := 0 to BMP.Height-1 do begin pPL := BMP.ScanLine[y]; for X := 0 to BMP.Width-1 do with pPL[X] do begin R := 255-R; G := 255-G; B := 255-B; end; end; end;
alors que la methode Canvas.Pixel (meme optimisée) : { athlon 2700+ @ 2Ghz / bitmap 640x480 = 1670..1680ms } procedure NegativizeCanvas(BMP : TBitmap); var Color : integer; RGB : array[0..2] of byte absolute color; N,X,Y : integer; begin BMP.PixelFormat := pf32bit; for Y := 0 to BMP.Height-1 do begin for X := 0 to BMP.Width-1 do begin Color := BMP.Canvas.Pixels[X,Y]; for N := 0 to 2 do RGB[N] := 255-RGB[N]; BMP.Canvas.Pixels[X,Y] := Color; end; end; end;et ce n'est qu'un simple negatif, imagine sur une rehausse des couleurs, des contrastes ou autres modfication complexe.... ensuite
il faut savoir qu'un Canvas n'a pas de réelle limite de coordonées ...
on peut trés bien aller a X=10000,Y=-5000 sur un canvas qui ne fait que
320x200 pixel. contrairement a ScanLine qui est reduit a l'interval 0..Width-1, 0..Height-1 et provoque une erreur si on sort de cette limite. Croc (click me)
|
|
mardi 24 octobre 2006 à 08:48:50 |
Re : Question sur l'utilisation des TBitmap dans les fonctions...

cerber943
|
Merci beaucoup du temps que tu as du passer pour me répondre, c'est très complet et très clair. Bravo ! Je n'ai plus qu'à remodifier mon code pour voir ce que cela m'a apporté et il est vrai que mon code était lent... je m'attend donc à avoir une agréable surprise lorsque j'aurais appliqué tes fonctions :) Puis-je encore abuser de ton temps et demander pourquoi lorsque tu veux créer des pointeurs, tu les définies comme étant des pointeurs de tableau d'une taille max ? Est-ce que la taille max a une importance ? Je pensais qu'un pointeur n'avait besoin que de savoir le type de donnée pointée, pas le nombre d'éléments de mémoire qui se trouve dans la zone pointée... Je me doute qu'il faille faire comme tu l'as mis mais c'était pour mieux comprendre.
Quoi qu'il en soit si tu n'as pas le temps de répondre tu auras déja répondu à ma question donc encore merci pour ton dévouement et ton efficacité !
|
|
mardi 24 octobre 2006 à 09:55:07 |
Re : Question sur l'utilisation des TBitmap dans les fonctions...

cerber943
|
Je précise que j'ai un problème lorsque j'utilise function CreateBitmap(BMP : TBitmap; const AWidth, AHeight : integer; const APixelFormat : TPixelFormat = pf32bit) : boolean; begin result := false; if not Assigned(BMP) then begin BMP := TBitmap.Create; BMP.Width := AWidth; BMP.Height:= AHeight; BMP.PixelFormat := APixelFormat; result := true; end; end;
Il semble que je sois obligé de mettre ma variable à nil avant d'appeler CreateBitmap. Lorsque je met : result:=nil; CreateBitmap(result,4,7);
result vaut toujours nil. Néanmoins si je rajoute var devant BMP dans la déclaration de CreateBitmap comme ceci :
function CreateBitmap(var BMP : TBitmap; const AWidth, AHeight : integer; const APixelFormat : TPixelFormat = pf32bit) : boolean; le problème semble résolu. En tout cas merci j'espère ne pas avoir fait d'erreur en mettant ce var devant BMP A+
|
|
mardi 24 octobre 2006 à 13:30:46 |
Re : Question sur l'utilisation des TBitmap dans les fonctions...

Guillemouze
|
c'est ce que j'allai dire, il manque un var devant le BMP de createBitmap et FreeBitmap aussi.
|
|
mardi 24 octobre 2006 à 22:30:45 |
Re : Question sur l'utilisation des TBitmap dans les fonctions...

f0xi
|
oui il manque le var... mais uniquement pour Create et Free. pour les autres on peu trés bien travailler sur le Bitmap d'un TImage donc pas de var. sinon, pour les pointeurs c'est une question inerrante a scanline. en effet les anciens bitmap etait limité a 2048 pixels de long. soit : array[0..2047] of ... mais maintenant, le format ayant evolué, la taille n'est plus limitée et donc on peu definir une taille min/max a ce buffer. quand on recupere pPL := BMP.ScanLine[Y], pPL contient tout les pixels de la ligne Y. ensuite on appel pPL[X] pour travailler sur le pixel X de la ligne Y. sincerement je crois avoir tenter une fois d'utiliser un tableau dynamique pour scanline, mais il me semble que ça ne fonctionne pas. j'explique aussi pourquoi j'utilise des structure Record. comme tu le sais un bitmap peut avoir un format de pixel different : pf8bit (byte) pf16bit (word) pf24bit (...) pf32bit (integer) le probleme, c'est que par exemple il n'existe pas de type scalaire 24bit (3x1byte). et donc il nous faut une structure record ou un tableau de 3 bytes : TPixel24 = record B,G,R : byte end; TPixel24 = array[0..2] of byte; pour le pf32bit, un structure record ou un integer est identique, sauf que la structure record offre quelques avantage, comme par exemple d'eviter de faire des SHL et SHR pour travailler sur lun des octet de couleur RGB. Croc (click me)
|
|
vendredi 4 avril 2008 à 17:05:21 |
Re : Question sur l'utilisation des TBitmap dans les fonctions...

kiwi200810
|
sal  ut les gas!!!!!!! quelle est l'avatage d'utiliser scanline par apport a getpixel je voudrai savoir que fait le fonction assign
|
|
vendredi 4 avril 2008 à 17:25:13 |
Re : Question sur l'utilisation des TBitmap dans les fonctions...
|
Cette discussion est classée dans : img, get, fonctions, height, tbitmap
Répondre à ce message
Sujets en rapport avec ce message
Impression d'un bitmap : Page Blanche [ par Francky23012301 ]
Salut à tous,Je travaille actuellement avec le composant TGraphXY de Kénavo. J'ai besoin de pouvoir l'imprimer en noir et blanc, j'utilise donc ce cod
Aide pour ce qui ressemble à un bug dans mon programme svp ... [ par cerber943 ]
Bonjour,Voici mon problème je cherche à réaliser une fonction qui récupere une image TBitmap la découpe en 16 zones égales et retourne un tableau de 1
chargement DLL dynamique avec fonctions [ par christophedlr ]
Bonsoir à tous,Dans mon logiciel, je prévois plusieurs langues possibles par fichiers DLL.J'ai trouvé sur delphipage, un moyen de charger dynamiquemen
Connaitre toute les fonctions d'une DLL [ par askil2000 ]
Bonjour,Certe, j'ai déja travaillé avec des DLL, mais je connaissais leurs fonctions et donc les appelais de manière dynamique.exemple :type TMyDll =
Création dynamique de TStringList et de TBitmap [ par sisi231 ]
Bonjour,je souhaiterais pouvoir créer dynamiquement (i.e. pendant l'exécution de mon programme) des TBitmap et des TstringList autant que je veux.L'en
Comment libérer un TBitmap résultant d'une fonction? [ par Caribensila ]
Salut à tous, Une question existentielle me tourmente...Je vous donne un petit exemple, ce sera plus simple: <font face="Verd
deux fonctions inconnues! [ par arfimounir ]
Salut à tous.Je veux quelqu'un qui peut me dire: que veux dire ces deux fonctions en delphi - inc( ) - trunc( )Et Merci.
Sur les expressions Qreport [ par leader2000 ]
Salut!S'il y a un doué (ou un habitué) dans l'utilisation du QuickReport pourrai-il me donner une liste expliquée sur quelques fonctions utilisables
Création dynamique [ par gabs77 ]
bonjour, je fais une création dynamique d'image comme un album en quelque sorte et, jusque là tout marche nickel, dont voici le script :var Form1:
Problème d'affichage d'une Image1.Canvas.Pen.Mode [ par cincap ]
Bonsoir à toutes et à tous,Je dispose de deux fiche, sur la 1ère (formvisu) je charge une photo dans un Timage et j'ai un Tprintersetupdialog, sur la
Livres en rapport
|
Derniers Blogs
TECHDAYS PARIS 2010 : PLAN DE MIGRATION VERS SHAREPOINT 2010TECHDAYS PARIS 2010 : PLAN DE MIGRATION VERS SHAREPOINT 2010 par ROMELARD Fabrice
Animé par: Arnault Nouvel et Antoine Dongois Le processus à prendre : Apprendre (découvrir la plateforme) Préparer (documenter l'historique et choisir la méthode de MAJ) Test (Test de MAJ) Implémenter (Effectuer la MAJ) Valid...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2010 : LA PLEINIèRE DU SECOND JOURTECHDAYS PARIS 2010 : LA PLEINIèRE DU SECOND JOUR par ROMELARD Fabrice
Après un retour sur l'histoire des TechDays de Paris et le fait que ce soit le plus gros event MS au monde (du fait de sa gratuité), le président de MS France (Eric Boustoullier) a fait une présentation de la vision Microsoft pour les années à venir...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice CRéATION D'UNE BASE DE DONNéE SOUS SQL AZURECRéATION D'UNE BASE DE DONNéE SOUS SQL AZURE par junarnoalg
Sans rentrer dans les détails, je me propose ici de faire un rapide tour de ce que propose SQL Azure.
SQL Azure est avant tout un service d'hébergement de base de données relationnelles construit sur SQL Server. Il permet aux entreprises d...
Cliquez pour lire la suite de l'article par junarnoalg TECHDAYS PARIS 2010 : LES SERVICES D'APPLICATIONS DANS SHAREPOINT 2010TECHDAYS PARIS 2010 : LES SERVICES D'APPLICATIONS DANS SHAREPOINT 2010 par ROMELARD Fabrice
Animé par: Xavier Moreels et Julien Bakmezdjian Ce sujet est lié au partage des applications comme services dans SharePoint 2010, ceci représente la possibilité de créer sa propre application qui sera utilisable comme ceux en standard : Search...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
DB-MAIN (9.1.0)DB-MAIN (9.1.0)DB-MAIN is a data-modeling and data-architecture tool. It is designed to help developers and anal... Cliquez pour télécharger DB-MAIN Xilisoft DPG Convertisseur (5.1.37.0120)XILISOFT DPG CONVERTISSEUR (5.1.37.0120)Xilisoft DPG Convertisseur offre aux fans de Nintendo DS une bonne solution leur permettant de dé... Cliquez pour télécharger Xilisoft DPG Convertisseur GraphicsGale (2.01.01)GRAPHICSGALE (2.01.01)GraphicsGale est un logiciel de PixelArt avec de nombreuse fonctionnalités permettant de réalisé ... Cliquez pour télécharger GraphicsGale Architecte 3D (Platinum 2010)ARCHITECTE 3D (PLATINUM 2010)Architecte 3D Platinium vous permet de concevoir facilement les plans votre future maison, de l'é... Cliquez pour télécharger Architecte 3D TeamViewer 5 (TeamViewer 5)TEAMVIEWER 5 (TEAMVIEWER 5)Dépanner un ami,expliquer une manipulation devient un jeu d'enfant.
Prise en main d'un autre ord... Cliquez pour télécharger TeamViewer 5
|