Skip to content

Instantly share code, notes, and snippets.

@prashanthrajagopal
Last active June 22, 2024 11:32
Show Gist options
  • Save prashanthrajagopal/05f8ad157ece964d8c4d to your computer and use it in GitHub Desktop.
Save prashanthrajagopal/05f8ad157ece964d8c4d to your computer and use it in GitHub Desktop.
Take a screenshot and save as jpeg in c++
#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;
}
@NeznanLik
Copy link

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