Take a screenshot in windows C
I want to take a screenshot in C on my windows machine and save it as jpg or bmp or whatever. Anyway, I tried to do it myself, everything is fine and works well, but it is ILLEGALLY SLOW as opposed to the key prt scr
- I wonder if there is a way to access the clipboard prt scr
and somehow paste it into the jpg / png file OR if there is a faster way to get all screen pixels. That's my code:
int main()
{
bitmap_t pic;
int i, j;
pic.width = GetSystemMetrics(SM_CXSCREEN);
pic.height = GetSystemMetrics(SM_CYSCREEN);
pic.pixels = (pixel_t**)malloc(sizeof(pixel_t*)*pic.width);
for(i = 0 ; i < pic.height ; i++)
{
pic.pixels[i] = (pixel_t*)malloc(sizeof(pixel_t)*pic.height);
}
HDC hdc = GetDC(NULL);
COLORREF c;
printf("Size of your monitor is %d by %d.\n", pic.width, pic.height);
for(i = 0 ; i < pic.width ; i++)
{
for(j = 0 ; j < pic.height ; j++)
{
c = GetPixel(hdc, i, j);
pic.pixels[i][j].red = (uint8_t)GetRValue(c);
pic.pixels[i][j].green = (uint8_t)GetGValue(c);
pic.pixels[i][j].blue = (uint8_t)GetBValue(c);
}
}
ReleaseDC(NULL, hdc);
save_png_to_file(&pic, "D:\\pic.png");
for(i = 0 ; i < pic.height ; i++)
{
free(pic.pixels[i]);
}
free(pic.pixels);
return 0;
}
The function save_png_to_file
works propely, the loop takes too long (my screen is 1366x768 and over a million loop entries) - why is it so slow when the key prt scr
makes it easy?
source to share
This is explained here:
http://msdn.microsoft.com/en-us/library/dd183402(v=vs.85).aspx
See function CaptureAnImage()
in example. The whole code is a little tricky because it is a complete win32 application, but it shows how to grab a sepcific window and save up filename.bmp
.
source to share
Hmm ... GetPixel()
really slow on its own and then looping it together with this many do-overs ... Can't be good. The function is BitBlt
faster than LOT - here's an example:
BOOL SaveToFile(HBITMAP hBitmap3, LPCTSTR lpszFileName)
{
HDC hDC;
int iBits;
WORD wBitCount;
DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;
BITMAP Bitmap0;
BITMAPFILEHEADER bmfHdr;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
HANDLE fh, hDib, hPal,hOldPal2=NULL;
hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else
wBitCount = 24;
GetObject(hBitmap3, sizeof(Bitmap0), (LPSTR)&Bitmap0);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap0.bmWidth;
bi.biHeight =-Bitmap0.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrImportant = 0;
bi.biClrUsed = 256;
dwBmBitsSize = ((Bitmap0.bmWidth * wBitCount +31) & ~31) /8
* Bitmap0.bmHeight;
hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC = GetDC(NULL);
hOldPal2 = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
GetDIBits(hDC, hBitmap3, 0, (UINT) Bitmap0.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
+dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);
if (hOldPal2)
{
SelectPalette(hDC, (HPALETTE)hOldPal2, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
}
fh = CreateFile(lpszFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);
return TRUE;
}
int screenCapture(int x, int y, int w, int h, LPCSTR fname)
{
HDC hdcSource = GetDC(NULL);
HDC hdcMemory = CreateCompatibleDC(hdcSource);
int capX = GetDeviceCaps(hdcSource, HORZRES);
int capY = GetDeviceCaps(hdcSource, VERTRES);
HBITMAP hBitmap = CreateCompatibleBitmap(hdcSource, w, h);
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap);
BitBlt(hdcMemory, 0, 0, w, h, hdcSource, x, y, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld);
DeleteDC(hdcSource);
DeleteDC(hdcMemory);
HPALETTE hpal = NULL;
if(SaveToFile(hBitmap, fname)) return 1;
return 0;
}
int main()
{
screenCapture(0, 0, GetSystemMetric, 768, "D:\\MyFirstScreeshot.bmp");
return 0;
}
source to share