cs_nader
Messages postés10Date d'inscriptionvendredi 4 avril 2003StatutMembreDernière intervention19 juillet 2010
-
24 août 2006 à 23:25
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 2021
-
31 août 2006 à 09:17
J'essaye de réaliser une petite application qui effectue une capture d'ecran en utilsant uniquement l'API Windows (donc eviter l'utilisation de TBitmap de l'unité Graphics), la fonction principale
produit un " HBitmap" mon problème est Comment Sauver ce "HBitmap" dans un fichier (*.bmp)? Merci d'avance pour vos réponses .
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 29 août 2006 à 03:48
Voici la solution (enfin je pense )
Testez et dites moi si ça fonctionne (normalement il n'y a plus de raisons)
procedure screenshot(shot: string);
var dibH : hBitmap;
bits : pointer;
info : TBITMAPINFO;
width,height : integer;
screenDC,dibDC : hDC;
f : fileof byte;
FileHeader : TBITMAPFILEHEADER;
ImgSize : Cardinal;
begin screenDC := getDC(getDeskTopWindow);
dibDC := createCompatibleDC(screenDC);
width := getDeviceCaps(screenDC,HORZRES);
height := getDeviceCaps(screenDC,VERTRES);
//info.bmiHeader.biXPelsPerMeter := round(getDeviceCaps(screenDC,LOGPIXELSX)*39.37);
//info.bmiHeader.biYPelsPerMeter := round(getDeviceCaps(screenDC,LOGPIXELSY)*39.37);
zeromemory(@info,sizeOf(info));
ImgSize := Width * Height * 3;
// Pour passer en 32 Bits il faut faire : ImgSize := Width * Height * 4;
// et mettre biBitCount := 32;
with info.bmiHeader do begin biSize : = sizeOf(TBITMAPINFOHEADER);
biWidth := width;
biheight := height;
biplanes := 1;
biBitCount := 24;
biSizeImage := ImgSize; // ceci manquait
biCompression := BI_RGB;
end ;
dibH : = createDIBSection(dibDC,info,DIB_RGB_COLORS,bits,0,0);
selectObject(dibDC,dibH);
bitblt(
dibDC,
0,0,width,height,
screenDC,
0,0,
SRCCOPY);
releaseDC(getDeskTopWindow,screenDC);
assignFile(f,shot);
reWrite(f);
if width and 3 <> 0 then width := 4*((width div 4)+1);
with fileHeader do begin bfType : = ord('B')+(ord('M')shl 8);
bfSize := sizeOf(TBITMAPFILEHEADER)+sizeOf(TBITMAPINFOHEADER)+ImgSize;
//bfOffBits := sizeOf(TBITMAPINFOHEADER);
// et la taille n'était pas correct
bfOffBits : = sizeOf(TBITMAPFILEHEADER)+sizeOf(TBITMAPINFOHEADER);
end;
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 25 août 2006 à 01:21
Un HBitmap est un LongWord qui correspond à un handle de bitmap.
Pour enregistrer ta capture d'écran dans un fichier, il te faudra passer par un bitmap, que ça te plaise ou pas.
Ca serait bien de nous montrer quelques lignes de code, ça expliquerait mieux ton problème.
Il faut cliquer sur réponse acceptée quand on répond à tes
questions et que la réponse te convient, et pourquoi pas mettre un
petit mot pour dire si ça marche, sinon pourquoi ça marche pas. Comme
ça on sait si on a bien fait de te répondre, ou si on aurait mieux fait
de faire autre chose.
Je dis ça par rapport aux questions que tu as déjà posées sur ce forum,
auxquelles il a été répondu, et qui sont toutes restées sans
commentaires de ta part.
C'est qu'ici, on est une communauté de gens qui aiment programmer en
Delphi et qui aiment aussi partager leurs compétences (on touche pas
d'argent pour ça).
cs_nader
Messages postés10Date d'inscriptionvendredi 4 avril 2003StatutMembreDernière intervention19 juillet 2010 25 août 2006 à 19:49
Premièrement, un petit mot pour " Caribensila ": ya absolument rien qui faire rire !?! C débile comme réponse !
2ement : j'ai pas poster assez de message pour remarquer qu'il ya un bouton [Réponse acceptée]. d'ailleur je me suis jamais connecté en tant que membre pour lire les réponses sur le forum, je les consulte en tant que visiteur . je pense que c pour ca que j'avait pa remarqué le bouton 'rep accepté'
3ement: Pourquoi a chaque fois que quelqun pose une question il faut qu'il y est quelque membres pour les prise de tête...?!
Pour la réponse de "Japee" j'ai rien contre, et je répète, je vien pas souvent sur le forum et je savait pa pour " Réponse accepté " ( j'avait pa remarqué ce bouton) et vraiment merci pour la réponse. et le seul sujet (dont je me rappelle) que j'ai consulter pour voir les réponses et celui a propos du 'type procédure' et on peut pa vraiment juger les réponses quand on ne sait pas.
Pour la réponse de " Caribensila " (si on peut appelé ça réponse) :tu peut la garder et en meme temp apprendre les bonne manière !
Pour ceux qui sont interréssé par le sujet : voici la fonction qui retourne le Handle du Bitmap:
Pour les étapes suivante (pour enregistrer le bitmap) ya une seule facon de se passer de l'unité Graphics (On peut bien se passer TBitmap si ca nous plait !), on peut se contenter de l'API Windows en passant par les étape suivantes:
Construire l'entete du fichier bitmap contenant les informations sur les dimensions, la palette de couleur, sa taille ...: d'abord la structure BITMAPFILEHEADER (type et taille du fichier) suivit du BITMAPINFOHEADER ( Dimension et format des couleurs) puis la structure du RGBQUAD ( table de couleur ou lé bloc de pixels).
on note que la fonction BitBlt nous servira pour construire le RGBQUAD qui est sous formes de bloc rectangulaire contenant les pixels du bitmap, en fete la a fonction BitBlt récupère les bits de chacun de ses bloc.
Pour la totalité du code ,il faudrait que je me documente encore sur les Header des bitmap. et si je répond pas suite a ce message c'est que je vient pas fréquement sur le forum, et j'essaye de participer au maximum et j'aime bien partager mes bout de codes et mes connaissances avec les autres et j'ai rien contre, donc si votre réponse servira au membres du forum vous pouvez l'ajouter, et si c'est pour prendre la tête veuillez s'abstenir ca n'aidera aucun membre de la communauté a progresser.
Merci
Vous n’avez pas trouvé la réponse que vous recherchez ?
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 27 août 2006 à 16:52
Salut,
J'ai déjà remarqué des cas où l'ordre des octets est inversé.
on a plus R,G,B mais B,G,R ...
( Mais pas le décalage dont parle Japee. Es-tu sûr, Japee? )
En Delphi le color est R,G,B.
Mais parfois on trouve des bitmap dont la structures est B,G,R (toujours en byte).
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 28 août 2006 à 12:17
Salut Caribensila,
J'ai vérifié.
Si au départ j'ai une valeur RGB 195, 106, 29 , elle sera modifiée ainsi : <gras>29, 195, 106. Si je recapture la capture obtenue, j'obtiens RGB </gras> 106, 29, 195. Et si je capture une troisième fois, je retombe sur les couleurs originelles, mdr...
Donc, en (re)capturant 3 fois, j'obtiens un bitmap dont les couleurs correspondent aux couleurs d'origine.
Je n'ai pas trop le temps de me pencher sur le problème (quoique le
sujet commence à me titiller), mais la solution doit être intéressante.
Alors, si quelqu'un a une idée... (les forts en graphisme, là...)
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 28 août 2006 à 14:31
Cirec > moi aussi, j'aimerais bien comprendre.
Au cas où le lien que je cite ne pointerait pas sur la même page (bien
qu'on ait XP tous les deux, mais j'utilise plus volontiers Firefox,
lol), je recopie ci-dessous le code que j'ai testé :
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 28 août 2006 à 23:47
Bon alors :
j'ai effectivement réussi à ouvrir l'image avec un décalage !!!!
en fait, chez moi, tout dépend avec quel utilitaire j'ouvre l'image
Avec "Paint" il l'ouvre correctement (sans décalage) ainsi qu'en l'ouvrant dans un TImage sous Delphi
Avec "Aperçu des Images" (de Windows) il l'affiche avec décalage
En suite en faisant une comparaison entre un Screen-Shoot dans un Bitmap et cette méthode :
j'obtiens une différence de taille de 2,3 Mo
Avec cette méthode le fichier fait 3,7 Mo = 1280*1024*3
Avec un Bitmap il fait 5,0Mo = 1280*1024*4
J'ai réussi à produire un fichier de taille identique mais il y a également un décalage avec les mêmes particularités que celles cités plus haut il n'y a que le décalage en couleur qui change
Voilà ça ne fait pas vraiment avancer la chose mais je rien trouvé d'autre pour l'instant
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 29 août 2006 à 03:57
J'ai oublié un petit commentaire :
//info.bmiHeader.biXPelsPerMeter := round(getDeviceCaps(screenDC,LOGPIXELSX)*39.37);
//info.bmiHeader.biYPelsPerMeter := round(getDeviceCaps(screenDC,LOGPIXELSY)*39.37);
// j'ai mis ces deux lignes en commentaire parce qu'elles ne servent à rien
// en effet l'auteur à affecté une valeur à info.bmiHeader.biXPelsPerMeter
// et info.bmiHeader.biYPelsPerMeter
//et la ligne suivante remplis de zéro la structure Info ?????
// en déplacant la ligne avant les deux plus haut l'information serait prise en compte mais il semblerait
//qu'elle ne soit pas utile ... à voir
zeromemory(@info,sizeOf(info));
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 29 août 2006 à 08:29
Pour l'instant, je n'ai qu'une chose à dire, c'est :
Bravo Cirec, tu es le meilleur...
Ca marche effectivement, et il ne manque plus d'octets comme auparavant.
Du coup, le code semble correspondre à ce que demandait la personne qui
a posé sa question, qui a ouvert sa gueule pour critiquer le forum, et
qui n'a jamais participé aux échanges. Dans ces conditions, c'est
facile de critiquer l'ambiance d'un forum pour dire qu'elle est je sais
plus quoi... prise de tête, je crois, bof...
Enfin, on s'est bien démerdés, entre nous, et on aura progressé encore
un peu dans la connaissance de la programation de l'api et de la
structure d'un fichier bmp...
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 29 août 2006 à 11:00
héhéhéhé
C'est vrai qu'il est formidable, ce Cirec. Et il ne lâche jamais le morceau, quelque soit l'heure!
Ce qui m'étonne encore c'est que ça passait bien dans "Paint" et pas dans l'"Aperçu"...Ce qui démontre bien, si c'est encore nécessaire, qu'il faut toujours tester ses codes "à mort" ;)