Skip to content

Instantly share code, notes, and snippets.

@SuperKogito
Last active November 10, 2023 09:08
Show Gist options
  • Save SuperKogito/a6383dddcf4ee459b979e12550cc6e51 to your computer and use it in GitHub Desktop.
Save SuperKogito/a6383dddcf4ee459b979e12550cc6e51 to your computer and use it in GitHub Desktop.
Code for my blog post <https://superkogito.github.io/blog/CaptureScreenUsingOpenCv.html> A snippet for capturing the screen content using OpenCV
/*****************************************************************************************************************
* \file CaptureSceenshotUsingOpenCV.cpp
* \brief capture screenshot using OpenCV and save it as a png.
*
* \author SuperKogito
* \date July 2020
*
* @note:
* references and sources:
* - http://msdn.microsoft.com/en-us/library/windows/window/dd183402%28v=vs.85%29.aspx
* - https://stackoverflow.com/questions/34466993/opencv-desktop-capture
* - https://stackoverflow.com/questions/14148758/how-to-capture-the-desktop-in-opencv-ie-turn-a-bitmap-into-a-mat
*
*****************************************************************************************************************/
#pragma once
#include <Windows.h>
#include <opencv2/opencv.hpp>
using namespace cv;
/**
* Create a Bitmap file header..
*
* @param hwindowDC : window handle.
* @param widht : image width.
* @param height : image height.
*
* @return Bitmap header.
*/
BITMAPINFOHEADER createBitmapHeader(int width, int height)
{
BITMAPINFOHEADER bi;
// create a bitmap
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = width;
bi.biHeight = -height; //this is the line that makes it draw upside down or not
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
return bi;
}
/**
* Capture a screen window as a matrix.
*
* @param hwnd : window handle.
*
* @return Mat (Mat of the captured image)
*/
Mat captureScreenMat(HWND hwnd)
{
Mat src;
// get handles to a device context (DC)
HDC hwindowDC = GetDC(hwnd);
HDC hwindowCompatibleDC = CreateCompatibleDC(hwindowDC);
SetStretchBltMode(hwindowCompatibleDC, COLORONCOLOR);
// define scale, height and width
int scale = 1;
int screenx = GetSystemMetrics(SM_XVIRTUALSCREEN);
int screeny = GetSystemMetrics(SM_YVIRTUALSCREEN);
int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
// create mat object
src.create(height, width, CV_8UC4);
// create a bitmap
HBITMAP hbwindow = CreateCompatibleBitmap(hwindowDC, width, height);
BITMAPINFOHEADER bi = createBitmapHeader(width, height);
// use the previously created device context with the bitmap
SelectObject(hwindowCompatibleDC, hbwindow);
// copy from the window device context to the bitmap device context
StretchBlt(hwindowCompatibleDC, 0, 0, width, height, hwindowDC, screenx, screeny, width, height, SRCCOPY); //change SRCCOPY to NOTSRCCOPY for wacky colors !
GetDIBits(hwindowCompatibleDC, hbwindow, 0, height, src.data, (BITMAPINFO*)&bi, DIB_RGB_COLORS); //copy from hwindowCompatibleDC to hbwindow
// avoid memory leak
DeleteObject(hbwindow);
DeleteDC(hwindowCompatibleDC);
ReleaseDC(hwnd, hwindowDC);
return src;
}
int main()
{
// capture image
HWND hwnd = GetDesktopWindow();
Mat src = captureScreenMat(hwnd);
// encode result
std::vector<uchar> buf;
cv::imencode(".png", src, buf);
// save img
cv::imwrite("Screenshot.png", src);
buf.clear();
return 0;
}
@shankslee2021
Copy link

How should I save png under windows xp 32bit?
I tried your code and it failed

@JMC-CR
Copy link

JMC-CR commented Nov 9, 2023

Hi any idea why buf.clear() is undefined?

@SuperKogito
Copy link
Author

Idk why you get this error since .clear() is definitely part of the vector class https://en.cppreference.com/w/cpp/container/vector/clear
make sure that you are defining your vector variable above the clearing and it is not inside some sort of a loop/if condition so it can be seen

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