Skip to content

Instantly share code, notes, and snippets.

@philip-goh
Created October 10, 2012 13:54
Show Gist options
  • Save philip-goh/3865787 to your computer and use it in GitHub Desktop.
Save philip-goh/3865787 to your computer and use it in GitHub Desktop.
Take a screenshot and write it out as a JPEG in C++ on Windows
#include <iostream>
#include <windows.h>
#include <gdiplus.h>
#include <memory>
using namespace Gdiplus;
using namespace std;
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0)
{
return -1; // Failure
}
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
{
return -1; // Failure
}
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; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}
void BitmapToJpg(HBITMAP hbmpImage, int width, int height)
{
Bitmap *p_bmp = Bitmap::FromHBITMAP(hbmpImage, NULL);
//Bitmap *p_bmp = new Bitmap(width, height, PixelFormat32bppARGB);
CLSID pngClsid;
int result = GetEncoderClsid(L"image/jpeg", &pngClsid);
if(result != -1)
std::cout << "Encoder succeeded" << std::endl;
else
std::cout << "Encoder failed" << std::endl;
p_bmp->Save(L"screen.jpg", &pngClsid, NULL);
delete p_bmp;
}
bool ScreenCapture(int x, int y, int width, int height, char *filename)
{
HDC hDc = CreateCompatibleDC(0);
HBITMAP hBmp = CreateCompatibleBitmap(GetDC(0), width, height);
SelectObject(hDc, hBmp);
BitBlt(hDc, 0, 0, width, height, GetDC(0), x, y, SRCCOPY);
BitmapToJpg(hBmp, width, height);
DeleteObject(hBmp);
return true;
}
int main() {
// Initialize GDI+.
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
int x1 = 0;
int y1 = 0;
int x2 = GetSystemMetrics(SM_CXSCREEN);
int y2 = GetSystemMetrics(SM_CYSCREEN);
ScreenCapture(x1, y1, x2 - x1, y2 - y1, "screen.jpg");
//Shutdown GDI+
GdiplusShutdown(gdiplusToken);
return 0;
}
@ulexec
Copy link

ulexec commented Sep 25, 2015

awesome, great job!

@MrBean2016
Copy link

Simple as it can be. If you get unresolved externals, do not forget to link with Gdiplus.lib

@Esya
Copy link

Esya commented Dec 23, 2015

Looks like filename isn't used anywhere in your ScreenCapture function

@sursu
Copy link

sursu commented Jan 13, 2016

Hi, I'm a C++ greenhorn.
Can anyone write how to "link with Gdiplus.lib"?

@amitv87
Copy link

amitv87 commented Feb 12, 2016

add this after #include
#pragma comment (lib,"Gdiplus.lib")

@geekcert
Copy link

geekcert commented Dec 11, 2016

WTF?!

what for a argument "filename" in function "bool ScreenCapture()"?
he does nothing

@Liftu
Copy link

Liftu commented Aug 8, 2017

Very great job, but the image seems to lose lot of quality

@jinwei908
Copy link

Great stuff! Thanks for this!

@vlhs-beep
Copy link

In mingw if error: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
Change: bool ScreenCapture(int x, int y, int width, int height, char *filename)
To: bool ScreenCapture(int x, int y, int width, int height, char *filename = (char *)"");

@graysuit
Copy link

Just copied your code and compiled !
+1 star for simplicity

@troyzhao
Copy link

niubility

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment