だけを使用してスクリーンショットを撮って保存しようとしていますctypes
。私は Windows API にあまり詳しくないので、Microsoft Developer Network のさまざまな例をかなり参考にしてきました。
から次のコードをMSDN
テンプレートとして使用して、ctypes で再作成しようとしました。
void SaveBitmap(char *szFilename,HBITMAP hBitmap)
{
HDC hdc=NULL;
FILE* fp=NULL;
LPVOID pBuf=NULL;
BITMAPINFO bmpInfo;
BITMAPFILEHEADER bmpFileHeader;
do{
hdc=GetDC(NULL);
ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
GetDIBits(hdc,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
if(bmpInfo.bmiHeader.biSizeImage<=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, &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(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
fwrite(&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);
GetDIBits
ただし、関数を成功させるのは運が悪いです。実際のスクリーン グラブ コードが正しいことにはある程度自信がありますが、保存コードが多くの問題を引き起こしています。イライラすることに、これらの関数が失敗する理由がわかりません。
私のPythonコード:
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)
print
各呼び出しにステートメントを追加しましたGetDIBits
が、確かに、それらはすべて失敗したコードを返しています。私はここで完全に困惑しています。