Ciao a tutti!
In diverse discussioni del forum per c++ è stato affrontato il problema del cattura schermo, ma non ho trovato soluzione al mio problema:
volevo implementare una classe in un mio programma per salvare lo schermo al verificarsi di alcuni errori nel programma principale in modo da poterli analizzare successivamente.
Di seguito vi mostro il codice riportato in un prorammino a se stante che funziona correttamente, ma il grosso problema è che non riesco a salvare file che siano più piccoli di 1,5 Mb. In caso di modifica delle impostazioni della risoluzione grafica riesco ad ottenere file di output più piccoli ma con 4 colori e quasi illegibili.
L' obiettivo è quello di ottenere un file bitmap con almeno 256 colori e di dimensioni dell' ordine di 100 - 200 kb.
Potete aiutarmi?
Di seguito il codice del programma:
#include <windows.h>
#include <stdio.h>
#include <wingdi.h>
#include <iostream.h> // per cout
#define BITSPERPIXEL 16
void cap(); //prototipo procedura cattura
int Tempo = 0;
int main() //main procedure
{
Tempo = GetTickCount();
cap();
return 0;
}
void cap()
{
BITMAPINFO bmi; //info del file di destinazione
BITMAPFILEHEADER bfh; //header del file di destinazione
int nWidth;
int nHeight;
HWND hWnd;
HDC hdc ;
HDC memDC;
HBITMAP hbm ;
HBITMAP hbmOld;
BYTE *pbBits;
HANDLE hfile;
// MOD
FILE *FileSave;
int infosize = 0;
int size = 0;
int bitsize = 0;
nWidth = GetSystemMetrics(SM_CXSCREEN); //dimensioni del rettangolo da catturare
nHeight = GetSystemMetrics(SM_CYSCREEN);
hWnd = GetDesktopWindow(); //creazione bitmap
hdc = GetDC(hWnd);
memDC = CreateCompatibleDC(hdc);
hbm = CreateCompatibleBitmap(hdc, nWidth, nHeight);
hbmOld = (HBITMAP)SelectObject(memDC, hbm); //hande to bitmap
BitBlt(memDC, 0, 0, nWidth, nHeight, hdc, 0, 0, SRCCOPY); //cattura bitmap
//modifica settaggio modalita grafica
ZeroMemory(&bmi,sizeof(BITMAPINFO));
bmi.bmiHeader.biSize=sizeof(bmi.bmiHeader);
bmi.bmiHeader.biWidth=GetSystemMetrics(SM_CXSCREEN );
bmi.bmiHeader.biHeight=GetSystemMetrics(SM_CYSCREE N);
bmi.bmiHeader.biPlanes=1;
bmi.bmiHeader.biBitCount=16;
bmi.bmiHeader.biCompression= BI_RGB; //BI_RLE4; // BI_RGB;
bmi.bmiHeader.biSizeImage=3 * bmi.bmiHeader.biWidth * bmi.bmiHeader.biHeight;
pbBits = (byte *) malloc(bmi.bmiHeader.biSizeImage); //alloca la memoria per l' immagine
// get image from Desktop
GetDIBits( memDC, //handle to device
hbm, //Handle to the bitmap
0, //first scan line to set in destination bitmap
bmi.bmiHeader.biHeight, //number of scan lines to copy
pbBits, //address of array for bitmap bits
&bmi, //address of structure with bitmap data
DIB_RGB_COLORS ); //RGB or palette index //DIB_PAL_COLORS);
infosize = sizeof(BITMAPINFOHEADER);
size = sizeof(BITMAPFILEHEADER); // + infosize + bmi.bmiHeader.biSizeImage ;
bfh.bfType='MB';
bfh.bfOffBits=sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bfh.bfSize=bmi.bmiHeader.biSizeImage + bfh.bfOffBits;
int CalcoloTeorico = (sizeof(BITMAPFILEHEADER) + bmi.bmiHeader.biSize +
bmi.bmiHeader.biClrUsed * sizeof(RGBQUAD) +
bmi.bmiHeader.biSizeImage);
cout << "Calcolo teorico dimensione file " << CalcoloTeorico << "\n";
cout << "Dimensione reale file " << size << "\n";
cout << " \n\n\n\n\n\n statistiche ";
cout << " dimensione BITMAPFILEHEADER " << sizeof(BITMAPFILEHEADER) << "\n";
cout << " dimensione infosize " << infosize << "\n";
cout << " dimensione biSizeImage "<< bmi.bmiHeader.biSizeImage << "\n";
cout << " Dimensione BSIZEIMAGE " << bmi.bmiHeader.biSizeImage << "\n";
cout << "size = " << size << "\n";
//buffer - size item - max number of item - pointer of file
//salvataggio su file
FileSave = fopen("PrimoTipo.bmp","wb");
if (FileSave != NULL)
{
fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), FileSave);
fwrite(&bmi, 1, infosize, FileSave);
fwrite((char *)pbBits, 1, bmi.bmiHeader.biSizeImage, FileSave);
fclose(FileSave);
}
// rilascio risorse
DeleteDC(memDC);
ReleaseDC(hWnd,hdc);
DeleteObject(hbm);
//bmi = NULL;
hfile = NULL;
pbBits = NULL;
free(pbBits);
cout << " Tempo utilizzato per creazione e salvataggio ms " << (GetTickCount() - Tempo) << "\n";
//exit(1);
}