分成两个部分,一个是用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;
}