. Hace una captura de pantalla y la comprime a JPEG (o PNG, con cambiar una línea se pueden elegir otros formatos) en memoria, por lo que es más rápido que otros códigos que guardan la captura en disco. Espero que a alguien le sirva
.ClsScreenShot.h:
Código
//--------------------------------------------------------------------------------------------------------- //Autor: Hacker_Zero //Fecha: 29-12-09 //Descripción: Clase ClsScreenShot, captura de pantalla comprimida en diferentes formatos //GDI+: Incuído en Windows XP o superior //Código liberado bajo la GNU Public License (GPL) <http://www.gnu.org/licenses/gpl-3.0.html> //--------------------------------------------------------------------------------------------------------- #ifndef SCREENSHOT_H #define SCREENSHOT_H #include <windows.h> #include <gdiplus.h> using namespace Gdiplus; class cScreenShot { public: cScreenShot(); ~cScreenShot(); HBITMAP CrearCapturaPantalla(DWORD dwLeft,DWORD dwTop,DWORD dwRight,DWORD dwBottom); CLSID GetEncoder(WCHAR* lpEnconder); LPSTR ComprimirImagen(HBITMAP hBitmap); VOID GuardarImagen(LPSTR lpFileName,LPSTR lpImage,DWORD ImageSize); DWORD ImageSize; RECT RC; private: GdiplusStartupInput GDIStartup; unsigned long GDIToken; EncoderParameters EP; ImageCodecInfo* ICI; CLSID Codec; IStream* lpIStream; unsigned int Codecs; unsigned int CodecSize; HDC hDC; HDC hCCDC; HBITMAP hBitmap; HBITMAP hOldBitmap; ULARGE_INTEGER StreamSize; LARGE_INTEGER StreamSeek; ULONG Read; DWORD dwRead; LPSTR lpBuffer; HANDLE hFile; }; #endif
ClsScreenShot.cpp
Código
#include "ClsScreenShot.h" cScreenShot::cScreenShot() { GdiplusStartup(&GDIToken,&GDIStartup,0); GetWindowRect(GetDesktopWindow(),&RC); } cScreenShot::~cScreenShot() { GdiplusShutdown(GDIToken); } HBITMAP cScreenShot::CrearCapturaPantalla(DWORD dwLeft,DWORD dwTop,DWORD dwRight,DWORD dwBottom) { hDC=CreateDCA("DISPLAY",0,0,0); hCCDC=CreateCompatibleDC(hDC); hBitmap=CreateCompatibleBitmap(hDC,dwRight,dwBottom); hOldBitmap=(HBITMAP)SelectObject(hCCDC,hBitmap); BitBlt(hCCDC,0,0,dwRight,dwBottom,hDC,dwLeft,dwTop,SRCCOPY); DeleteDC(hDC); DeleteDC(hCCDC); return hBitmap; } CLSID cScreenShot::GetEncoder(WCHAR* lpEnconder) { GetImageEncodersSize(&Codecs,&CodecSize); ICI=(ImageCodecInfo*)GlobalAlloc(GPTR,CodecSize); GetImageEncoders(Codecs,CodecSize,ICI); for(DWORD i=1;wcscmp(ICI[i-1].MimeType,lpEnconder);i++) { Codec=ICI[i].Clsid; } GlobalFree(ICI); return Codec; } LPSTR cScreenShot::ComprimirImagen(HBITMAP hBitmap) { Bitmap bmp(hBitmap,NULL); CreateStreamOnHGlobal(NULL,TRUE,(LPSTREAM*)&lpIStream); Codec=GetEncoder(L"image/jpeg"); //~Codec=GetEncoder(L"image/png"); ~// EncoderParameters EP; DWORD Quality=40; EP.Count=1; EP.Parameter[0].NumberOfValues=1; EP.Parameter[0].Guid=EncoderQuality; EP.Parameter[0].Type=EncoderParameterValueTypeLong; EP.Parameter[0].Value=&Quality; //bmp.SetResolution(550,600); bmp.Save(lpIStream,&Codec,&EP); StreamSeek.QuadPart=0; lpIStream->Seek(StreamSeek,STREAM_SEEK_END,&StreamSize); lpIStream->Seek(StreamSeek,STREAM_SEEK_SET,NULL); lpBuffer=(LPSTR)GlobalAlloc(GPTR,(SIZE_T)StreamSize.QuadPart); lpIStream->Read(lpBuffer,(ULONG)StreamSize.QuadPart,&Read); ImageSize=(DWORD)Read; return lpBuffer; } VOID cScreenShot::GuardarImagen(LPSTR lpFileName,LPSTR lpImage,DWORD ImageSize) { hFile=CreateFileA(lpFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,0,CREATE_ALWAYS,0,0); WriteFile(hFile,lpImage,ImageSize,&dwRead,0); CloseHandle(hFile); }
Ejemplo de uso:
Código
ClsScreenShot miScreenShot; //Creamos una captura HBITMAP hBitmap=miScreenShot.CrearCapturaPantalla(miScreenShot.RC.left,miScreenShot.RC.top,miScreenShot.RC.right,miScreenShot.RC.bottom); //Convertimos el Bitmap a Jpeg LPSTR JpegImage=miScreenShot.ComprimirImagen(hBitmap); //La guardamos en disco miScreenShot.GuardarImagen("C:\\captura.jpeg",JpegImage,miScreenShot.ImageSize);
Saludos






Autor




En línea



.
. A ver si alguien puede mejorar la clase haciendo que sea más rápida, GDI+ deja mucho que desear en cuanto a velocidad
.
, aunque no tanto como Jpeg... claro que no tiene perdida( 
