Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2007
    Messaggi
    12

    [C++] Screenshot con salvataggio file

    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);
    }

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Le dimensioni dipendono dall'area prelevata e non puoi gestirla tu.

    Se prendi un'area di 1024*768 in cui un byte rappresenta il colore di un pixel, solamente di informazioni grafiche hai 786432 byte a cui aggiungerai quelli della "struttura" della bitmap.

    Per ridurre la dimensione, devi utilizzare un formato di tipo jpg (o comunque compresso) ma, ovviamente, non puoi utilizzare questo codice ...

  3. #3
    Utente di HTML.it
    Registrato dal
    May 2007
    Messaggi
    12
    Ok, il discorso fila, ma ho visto dei programmi già compilati che fanno degli screenshot con salvataggio, in cui c'è la possibilità di salvare il file di output in diversi formati... Tra questi c'è anche il bitmap ed il prodotto è un file di circa 120 Kb con risoluzione di 256 colori.

    A questo punto devo pensare che si tratti semplicemente di un file jpg rinominato in bitmap... o no?!?!

    In ogni caso dato che non mi interessa il tipo di file, ma volevo solo ottimizzare il prodotto in output, potresti consigliarmi un qualche algoritmo che soddisfi le mie necessità con la produzione di un file grafico compresso come il jpg?

    Tieni solo presente che sto sviluppando in Visual C++ versione 6, e quindi in modalità unmanagement, senza utilizzare il framework....

    Grazie ancora!!!

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Bisogna capire se quei file di cui parli sono effettivamente bmp standard o in un altro formato. Se le hai, falle scaricare e si vede come sono fatte ...

    Se vuoi salvare il file in formato jpg, ti devi affidare a delle librerie (magari open source) che lo fanno.

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2007
    Messaggi
    12
    Dovrei ritrovare quel programma per verificare gli header dei file di output...

    Comunque se trovo qualche libreria o altro che finalizzi il mio scopo ti illustrerò la soluzione... conosci qualche sito dove poter scaricare librerie per C++ ?

    Ciao Ciao!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.