Last active
October 23, 2024 13:14
-
-
Save prashanthrajagopal/05f8ad157ece964d8c4d to your computer and use it in GitHub Desktop.
Take a screenshot and save as jpeg in c++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <windows.h> | |
#include <gdiplus.h> | |
#include <time.h> | |
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) { | |
using namespace Gdiplus; | |
UINT num = 0; | |
UINT size = 0; | |
ImageCodecInfo* pImageCodecInfo = NULL; | |
GetImageEncodersSize(&num, &size); | |
if(size == 0) | |
return -1; | |
pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); | |
if(pImageCodecInfo == NULL) | |
return -1; | |
GetImageEncoders(num, size, pImageCodecInfo); | |
for(UINT j = 0; j < num; ++j) | |
{ | |
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) | |
{ | |
*pClsid = pImageCodecInfo[j].Clsid; | |
free(pImageCodecInfo); | |
return j; | |
} | |
} | |
free(pImageCodecInfo); | |
return 0; | |
} | |
void gdiscreen() { | |
using namespace Gdiplus; | |
IStream* istream; | |
HRESULT res = CreateStreamOnHGlobal(NULL, true, &istream); | |
GdiplusStartupInput gdiplusStartupInput; | |
ULONG_PTR gdiplusToken; | |
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); | |
{ | |
HDC scrdc, memdc; | |
HBITMAP membit; | |
scrdc = ::GetDC(0); | |
int Height = GetSystemMetrics(SM_CYSCREEN); | |
int Width = GetSystemMetrics(SM_CXSCREEN); | |
memdc = CreateCompatibleDC(scrdc); | |
membit = CreateCompatibleBitmap(scrdc, Width, Height); | |
HBITMAP hOldBitmap =(HBITMAP) SelectObject(memdc, membit); | |
BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY); | |
Gdiplus::Bitmap bitmap(membit, NULL); | |
CLSID clsid; | |
GetEncoderClsid(L"image/jpeg", &clsid); | |
// bitmap.Save(L"screen.jpeg", &clsid, NULL); // To save the jpeg to a file | |
bitmap.Save(istream, &clsid, NULL); | |
// Create a bitmap from the stream and save it to make sure the stream has the image | |
// Gdiplus::Bitmap bmp(istream, NULL); | |
// bmp.Save(L"t1est.jpeg", &clsid, NULL); | |
// END | |
delete &clsid; | |
DeleteObject(memdc); | |
DeleteObject(membit); | |
::ReleaseDC(0,scrdc); | |
} | |
GdiplusShutdown(gdiplusToken); | |
} | |
int main() | |
{ | |
clock_t t1 = clock(); | |
int i; | |
int iterations = 10; | |
for(i=0;i<iterations;i++){ | |
gdiscreen(); | |
} | |
clock_t t2 = clock(); | |
printf("%d iterations: %0.0f fps\n", iterations, iterations/((double)(t2 - t1) / CLOCKS_PER_SEC)); | |
return 0; | |
} |
Saving screenshot into a byte array:
std::vector<unsigned char> GetScreenshot() {
IStream* istream;
HRESULT res = CreateStreamOnHGlobal(NULL, true, &istream);
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
HDC scrdc, memdc;
HBITMAP membit;
scrdc = ::GetDC(0);
int Height = GetSystemMetrics(SM_CYSCREEN);
int Width = GetSystemMetrics(SM_CXSCREEN);
memdc = CreateCompatibleDC(scrdc);
membit = CreateCompatibleBitmap(scrdc, Width, Height);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(memdc, membit);
BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
Gdiplus::Bitmap bitmap(membit, NULL);
CLSID clsid;
GetEncoderClsid(L"image/jpeg", &clsid);
bitmap.Save(istream, &clsid, NULL);
STATSTG statstg;
istream->Stat(&statstg, STATFLAG_NONAME);
ULARGE_INTEGER uliSize = statstg.cbSize;
// Allocate buffer and read the stream into it
std::vector<unsigned char> buffer(uliSize.LowPart);
LARGE_INTEGER liZero = {};
istream->Seek(liZero, STREAM_SEEK_SET, NULL);
ULONG bytesRead;
istream->Read(buffer.data(), uliSize.LowPart, &bytesRead);
return buffer;
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
i spent time to find out how to start it working. so i did. on windows 7. to right code is:
but if you compile it with :
gcc screenshot.cpp -o out.exe -lgdiplus -mwindows -lole32
it gives error:
undefined reference to __gxx_personality_v0' ...
so the right command to compile it is :
gcc screenshot.cpp -o out.exe -lgdiplus -mwindows -lole32 -static-libgcc -Wl,-Bstatic -lstdc++
have a nice day!