Note that there are some explanatory texts on larger screens.

plurals
  1. POGetDIBits failing when trying to save screenshot with ctypes?
    primarykey
    data
    text
    <p>I'm attempting to take and save a screenshot using just <code>ctypes</code>. I'm not terrifically familiar with the Windows API, so I've been leaning pretty heavily on the various example in the Microsoft Developer Network. </p> <p>I've been using the following code from the <code>MSDN</code> as a template to try to recreate with ctypes. </p> <pre><code>void SaveBitmap(char *szFilename,HBITMAP hBitmap) { HDC hdc=NULL; FILE* fp=NULL; LPVOID pBuf=NULL; BITMAPINFO bmpInfo; BITMAPFILEHEADER bmpFileHeader; do{ hdc=GetDC(NULL); ZeroMemory(&amp;bmpInfo,sizeof(BITMAPINFO)); bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); GetDIBits(hdc,hBitmap,0,0,NULL,&amp;bmpInfo,DIB_RGB_COLORS); if(bmpInfo.bmiHeader.biSizeImage&lt;=0) bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; if((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage))==NULL) { //MessageBox( NULL, "Unable to Allocate Bitmap Memory", break; } bmpInfo.bmiHeader.biCompression=BI_RGB; GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &amp;bmpInfo, DIB_RGB_COLORS); if((fp = fopen(szFilename,"wb"))==NULL) { //MessageBox( NULL, "Unable to Create Bitmap File", "Error", MB_OK|MB_ICONERROR); break; } bmpFileHeader.bfReserved1=0; bmpFileHeader.bfReserved2=0; bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage; bmpFileHeader.bfType='MB'; bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); fwrite(&amp;bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp); fwrite(&amp;bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp); fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp); }while(false); if(hdc) ReleaseDC(NULL,hdc); if(pBuf) free(pBuf); if(fp) fclose(fp); </code></pre> <p>However, I'm having terrible luck getting the <code>GetDIBits</code> function to succeed. I'm moderately confident that I've got the actual screengrab code correct, but the save code is giving me a lot of trouble. And frustratingly, I'm not sure <em>why</em> these functions are failing. </p> <p>My Python code: </p> <pre><code>libc = ctypes.cdll.msvcrt # handle to the entire desktop Window hdc = windll.user32.GetDC(None) # DC for the entire window h_dest = windll.gdi32.CreateCompatibleDC(hdc) width = windll.user32.GetSystemMetrics(SM_CXSCREEN) height = windll.user32.GetSystemMetrics(SM_CYSCREEN) hb_desktop = windll.gdi32.CreateCompatibleBitmap(hdc, width, height) windll.gdi32.SelectObject(h_dest, hb_desktop) print windll.gdi32.BitBlt(h_dest, 0,0, width, height, hdc, 0, 0, 'SRCCOPY') # Save Section # ============== bmp_info = BITMAPINFO() bmp_header = BITMAPFILEHEADER() hdc = windll.user32.GetDC(None) bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) DIB_RGB_COLORS = 0 print windll.gdi32.GetDIBits(hdc, hCaptureBitmap, 0,0, None, byref(bmp_info), DIB_RGB_COLORS) bmp_info.bmiHeader.biSizeImage = bmp_info.bmiHeader.biWidth *abs(bmp_info.bmiHeader.biHeight) * (bmp_info.bmiHeader.biBitCount+7)/8; pBuf = (c_char * bmp_info.bmiHeader.biSizeImage)() BI_RGB = 0 bmp_info.bmiHeader.biCompression = BI_RGB print windll.gdi32.GetDIBits(hdc, hCaptureBitmap, 0, bmp_info.bmiHeader.biHeight, pBuf, byref(bmp_info), 0x00) bmp_header.bfReserved1 = 0 bmp_header.bfReserved2 = 0 bmp_header.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmp_info.bmiHeader.biSizeImage bmp_header.bfType = 0x4D42 bmp_header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) fp = libc.fopen('test.bmp',"wb") libc.fwrite(byref(bmp_header), sizeof(BITMAPFILEHEADER), 1, fp) libc.fwrite(byref(bmp_info.bmiHeader), sizeof(BITMAPFILEHEADER), 1, fp) libc.fwrite(pBuf, bmp_info.bmiHeader.biSizeImage, 1, fp) </code></pre> <p>I've added <code>print</code> statements to each <code>GetDIBits</code> call, and sure enough, they're all returning a failed code. I'm completely stumped here. </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload