screenshoot + jpeg

screenshoot + jpeg - C - Programmation

Marsh Posté le 11-12-2007 à 21:30:01    

Bonjour,
 
J'esseye de faire un screen de mon écran avec l'api windows et ensuite de faire un fichier .jpg de ce screen.
 
Voici mon code:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <jpeglib.h>
#include <setjmp.h>
 
HBITMAP CreateHbitmap(HDC *hdcCompatible, UINT *height, UINT *width)
{
 HDC hdcscreen;
 HBITMAP hbmscreen;
   
 hdcscreen=GetDC(NULL);
 *hdcCompatible=CreateCompatibleDC(hdcscreen);
 *height=GetDeviceCaps(hdcscreen, VERTRES);
 *width=GetDeviceCaps(hdcscreen, HORZRES);
 
 /*creation du bitmap compatible*/
 hbmscreen=CreateCompatibleBitmap(hdcscreen, *height, *width);
 
 /*select le bitmap dans le dc compatible*/
 SelectObject(*hdcCompatible, hbmscreen);
   
 /*capture de l'image*/
 BitBlt(*hdcCompatible, 0, 0, GetDeviceCaps(hdcscreen, HORZRES), GetDeviceCaps(hdcscreen, VERTRES), hdcscreen, 0, 0, SRCCOPY);
   
 return hbmscreen;
}
 
PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hbm)
{
 BITMAP bmp;
 PBITMAPINFO pbmi;
 WORD cClrBits;
 GetObject(hbm, sizeof(BITMAP), (LPSTR)&bmp);
 cClrBits=(WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
   
 if(cClrBits==1)
  cClrBits=1;
 else if(cClrBits<=4)
  cClrBits=4;
 else if(cClrBits<=8)
  cClrBits=8;
 else if(cClrBits<=16)
  cClrBits=16;
 else if(cClrBits<=24)
  cClrBits=24;
 else  
  cClrBits=32;
   
 if(cClrBits != 24)  
  pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< cClrBits));  
 else  
  pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));  
 
 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);  
 pbmi->bmiHeader.biWidth = bmp.bmWidth;  
 pbmi->bmiHeader.biHeight = bmp.bmHeight;  
 pbmi->bmiHeader.biPlanes = bmp.bmPlanes;  
 pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;  
 if (cClrBits < 24)  
  pbmi->bmiHeader.biClrUsed = (1<<cClrBits);  
         
 pbmi->bmiHeader.biCompression = BI_RGB;  
     
 pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8 * pbmi->bmiHeader.biHeight;  
     
 pbmi->bmiHeader.biClrImportant = 0;  
 return pbmi;  
}
 
int main()
{
 HDC hdcCompatible;
 UINT scanlines, width;
 
 HBITMAP hbm=CreateHbitmap(&hdcCompatible, &scanlines, &width);
 PBITMAPINFO pbmi=CreateBitmapInfoStruct(hbm);
 
 JSAMPLE *image_buffer = malloc(pbmi->bmiHeader.biSizeImage);
 GetDIBits(hdcCompatible, hbm, 0, scanlines, image_buffer, pbmi, DIB_RGB_COLORS);
 
 int image_height=scanlines;  
 int image_width=width;  
 
 FILE* outfile;  
 int quality = 50, row_stride;
 JSAMPROW row_pointer[1];
 
 /* Parametres de la compression JPEG */
 struct jpeg_compress_struct cinfo;
 
 /* Pour la gestion des erreurs */
 struct jpeg_error_mgr jerr;
 
 /* Allocation et initialisation des parametres de compression */
 cinfo.err = jpeg_std_error(&jerr);
 jpeg_create_compress(&cinfo);
 
 /* Ouverture du fichier en ecriture */
 outfile=fopen("toto.jpg","wb" );
 if (outfile==NULL)
 {  
  printf("\n- Grave erreur a l'ouverture de %s.jpg -\n", "toto" );
  exit(-1);
 }
 jpeg_stdio_dest(&cinfo, outfile);
 
 /* Choix des parametres de compression */
 cinfo.image_width = image_width;       /* Taille de l'image */
 cinfo.image_height = image_height;
 cinfo.input_components = 3;            /* Nombre de couleurs par pixel */
 cinfo.in_color_space = JCS_RGB;        /* colorspace of input image */
 jpeg_set_defaults(&cinfo);
 
 jpeg_set_quality(&cinfo, quality, TRUE);
 jpeg_start_compress(&cinfo, TRUE);
 
 row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
 
 while (cinfo.next_scanline < cinfo.image_height)
 {
  row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
  (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
 }
 
 jpeg_finish_compress(&cinfo);
 fclose(outfile);
 jpeg_destroy_compress(&cinfo);
 
 return 0;
}


 
Le fichier jpeg est bien créé mais il ne contient rien qui ressemble à un screen de mon écran !
 
Savez-vous pourquoi ?
Pour compiler : gcc bmp.c -lgdi32 -ljpeg
 
Merci...


Message édité par casafa le 11-12-2007 à 21:51:05
Reply

Marsh Posté le 11-12-2007 à 21:30:01   

Reply

Marsh Posté le 11-12-2007 à 23:19:42    

Euh, déjà t'es vraiment sûr de récupérer un bitmap 24bits ? Le format que s'attends ton code JPEG est du RGB 24bits top-down.
 
Un bitmap 24bits windows est de type BGR bottom-up (sauf si tu spécifie une hauteur négative), avec les lignes paddés sur 32bits.
 
Donc, il y a des conversions à faire dans tous les cas.
 
Edit: arf, sinon il y a gdi+ qui permet de faire ce genre de chose en nettement moins gore que gdi. Mais c'est du C++ et il faudra un peu bidouiller pour faire passer ça avec MinGW. C.f http://msdn2.microsoft.com/en-us/library/ms535407.aspx


Message édité par tpierron le 11-12-2007 à 23:38:32
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed