screenshoot + jpeg - C - Programmation
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
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