Windows API用以实现屏幕截图的方法

分成两个部分,一个是用getScrnBmp函数使用Windows API获取BMP图像,getJpg函数使用atlimage类实现将bmp压缩成jpg格式,注意不像jpeglib一样,压缩的出的jpg图像是无法选择清晰度的。

struct scrnStrc
{
	BYTE *bff;
	int sz;
};


struct scrnStrc* ScrnCls::getScrnBmp() 
{


//得到设备屏幕
	HDC hDc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
	int wdth, hght;

	wdth = GetSystemMetrics(SM_CXSCREEN);
	hght = GetSystemMetrics(SM_CYSCREEN);   //获得屏幕像素数

	HDC hMDc = CreateCompatibleDC(hDc);  //创建一个与指定设备兼容的内存设备上下文环境

	HBITMAP hBmp = CreateCompatibleBitmap(hDc, wdth, hght); //创建与指定的设备环境相关的设备兼容的位图
	SelectObject(hMDc, hBmp);  //选择一对象到指定的设备上下文环境中 将hBmp送到hMDc上下文环境中
	BITMAP bmp;

	GetObject(hBmp, sizeof(bmp), &bmp);      //获取图像信息

	BitBlt(hMDc, 0, 0, wdth, hght, hDc, 0, 0, SRCCOPY);   //从hDc拷贝到hMDc

	byte* byt;
	DWORD sz;

	ScrnCls::getJpg(hBmp,&byt,&sz);


	struct scrnStrc  *strc=(struct scrnStrc *)malloc(sizeof(struct scrnStrc));

	strc->bff =byt;
	strc->sz =sz;

	cnt++;

	return strc;

}

int ScrnCls::getJpg(HBITMAP hBmp,byte ** bytArr,DWORD * sz)
{
	CImage *img= new CImage;

	img->Attach(hBmp);

	//HGLOBAL hg;

	//hg = GlobalAlloc(GMEM_NODISCARD | GMEM_ZEROINIT | GMEM_MOVEABLE, 0x100000);

	IStream* is=NULL;

	CreateStreamOnHGlobal(NULL, FALSE, &is);  //不需要申请HGlobal空间

	img->Save(is, Gdiplus::ImageFormatJPEG);

	LARGE_INTEGER li;

	li.QuadPart = 0;

	is->Seek(li, STREAM_SEEK_SET, NULL);  //把流的位置移动到开始处

	byte* jpgBytArr;

	STATSTG stt;

	is->Stat(&stt, STATFLAG_DEFAULT);

	DWORD szArr,szWrt=0;

	szArr = (DWORD)stt.cbSize.LowPart;

	jpgBytArr = (byte*)malloc(szArr + 0x1000);


	memset(jpgBytArr, 0, sizeof(jpgBytArr));

	is->Read(jpgBytArr, szArr, &szWrt);

	*sz = szWrt;

	//释放资源
	is->Release();

	*bytArr = jpgBytArr;

	return 0;
}

你可能感兴趣的:(C\C++,windows,winapi,c++)