用MFC很容易把当前屏幕截取,并显示在自己程序的UI上。以对话框为例,在执行绘制的单元(比如OnPaint)中调用下面这个函数就能做到:
BOOL CSrnShotDlg::GetMyScreen(
CDC *pdc // 目标DC
)
{
CDC dc;
dc.CreateDC("DISPLAY", NULL, NULL, NULL); // 屏幕DC
CRect clientRect;
GetClientRect(clientRect); // 对话框矩形区域
pdc->BitBlt(0, 0, // 起始位置
clientRect.Width(),clientRect.Height(), // 宽高
&dc, // 源CDC对象
0, 0, // 源位置
SRCCOPY // 复制方法
);
dc.DeleteDC();
return TRUE; }
|
void ConvertToGray (CDC * pdc)
{
for (int xx = 0; xx < clientRect.right ; xx ++)
for (int yy = 0; yy < clientRect.bottom ; yy ++)
{
COLORREF crTemp = pdc->GetPixel(xx,yy);
BYTE pixelR = GetRValue(crTemp);
BYTE pixelG = GetGValue(crTemp);
BYTE pixelB = GetBValue(crTemp);
BYTE gray = (BYTE) (pixelR * 0.299 + pixelG * 0.587 +pixelB * 0.114);
pdc->SetPixelV(xx,yy,RGB(gray, gray, gray));
}
}
BOOL CSrnShotDlg::GetMyScreen(
CDC *pdc // 目标DC
)
{
CDC dc;
dc.CreateDC("DISPLAY", NULL, NULL, NULL); // 屏幕DC
CRect clientRect;
GetClientRect(clientRect); // 对话框矩形区域
CDC *pMemDC = NULL; // 兼容DC
pMemDC = new CDC;
if (!pMemDC)
return FALSE;
pMemDC->CreateCompatibleDC(&dc);
ShowWindow(SW_HIDE);
pMemDC->BitBlt(0, 0,
clientRect.Width(), clientRect.Height(),
&dc, 0, 0, SRCCOPY);
ConvertToGray(pMemDC);
pdc->BitBlt(0, 0, // 起始位置
clientRect.Width(),clientRect.Height(), // 宽高
pMemDC, // 源CDC对象
0, 0, // 源位置
SRCCOPY // 复制方法
);
pMemDC->DeleteDC();
delete pMemDC;
dc.DeleteDC();
return TRUE;
}
|
#define BITS24 (int)(1024 * 768 * 3)
void ConvertToGray24(CBitmap *pBmp)
{
LPBYTE lpbits = NULL;
lpbits = new BYTE[BITS24];
if (!lpbits)
return;
ZeroMemory(lpbits, BITS24);
pBmp->GetBitmapBits(BITS24, lpbits);
for (int index = 0, j = 0, k = 0; index < BITS24; index ++)
{
lpbits[index] = (BYTE)(0.114 * lpbits[index]);
j = index + 1; k = index + 2;
lpbits[j] = (BYTE)(0.587 * lpbits[j]);
lpbits[k] = (BYTE)(0.299 * lpbits[k]);
lpbits[index] += lpbits[j] + lpbits[k];
lpbits[j] = lpbits[index];
lpbits[k] = lpbits[index];
index = k;
}
pBmp->SetBitmapBits(BITS24, lpbits);
delete [] lpbits;
}
|
#define GetRValueX(rgb) ((BYTE)(rgb) & 0x1f)
#define GetGValueX(rgb) ((BYTE)(((rgb) & 0x07E0) >> 5))
#define GetBValueX(rgb) ((BYTE)(((rgb) & 0xF800) >> 11))
#define RGBX(r,g,b) \
((WORD)(((BYTE)(r)|((WORD)((BYTE)(g))<<5))|(((WORD)(BYTE)(b))<<11)))
|
#define BITS16 (int)(1024 * 768 * 2)
void ConvertToGray16(CBitmap *pBmp)
{
LPBYTE lpbits = NULL;
WORD *wBits;
lpbits = new BYTE[BITS16];
if (!lpbits)
return;
ZeroMemory(lpDibits, BITS16);
pBmp->GetBitmapBits(BITS16, lpbits);
for (int index = 0, j = 0, k = 0; index < BITS16; index ++)
{
wBits = (WORD *)(lpbits + index);
BYTE pixelR = GetRValueX(*wBits) * 2;
BYTE pixelG = GetGValueX(*wBits) ; // 注意系数
BYTE pixelB = GetBValueX(*wBits) * 2;
BYTE gray =(BYTE) (pixelR * 0.299 + pixelG * 0.587 +pixelB * 0.114);
*wBits = RGBX(gray / (BYTE)2, gray, gray / (BYTE)2);
index ++;
}
pBmp->SetBitmapBits(BITS16, lpbits);
delete [] lpbits;
}
|
BOOL CSrnShotDlg::GetMyScreen(
CDC *pdc // 目标DC
)
{
CDC dc;
dc.CreateDC("DISPLAY", NULL, NULL, NULL); // 屏幕DC
CRect clientRect;
GetClientRect(clientRect); // 对话框矩形区域
CDC *pMemDC = NULL; // 兼容DC
CBitmap *pBmp = NULL; // 兼容位图
pMemDC = new CDC;
if (!pMemDC)
return FALSE;
pMemDC->CreateCompatibleDC(&dc);
pBmp = new CBitmap;
if (!pBmp)
{
pMemDC->DeleteDC();
delete pMemDC;
return FALSE;
}
pBmp->CreateCompatibleBitmap(&dc, clientRect.Width(),clientRect.Height());
pMemDC->SelectObject(pBmp);
ShowWindow(SW_HIDE);
pMemDC->BitBlt(0, 0,
clientRect.Width(), clientRect.Height(),
&dc, 0, 0, SRCCOPY);
switch(pMemDC->GetDeviceCaps(BITSPIXEL))
{
case: 16
ConvertToGray16(pBmp);
break;
case: 24
ConvertToGray24(pBmp);
break;
case: 32
ConvertToGray32(pBmp); //未给出
break;
default:
pBmp->DeleteObject();
pMemDC->DeleteDC();
delete pBmp;
delete pMemDC;
dc.DeleteDC();
return FALSE;
}
pdc->BitBlt(0, 0, // 起始位置
clientRect.Width(),clientRect.Height(), // 宽高
pMemDC, // 源CDC对象
0, 0, // 源位置
SRCCOPY // 复制方法
);
pBmp->DeleteObject();
pMemDC->DeleteDC();
delete pBmp;
delete pMemDC;
dc.DeleteDC();
return TRUE;
}
|
----------------------------------------------------
附文件读取
ConvertBmp24ToBmp256
{
FILE *fp = fopen("test.bmp","rb");
if(!fp)return;
BITMAPFILEHEADER hdr;
fread(&hdr,1,sizeof(hdr),fp);
if(!(((hdr.bfType & 0xff) == 'B') && ((hdr.bfType >> 8) == 'M')))
{
fclose(fp);
return;
}
BITMAPINFOHEADER bih;
fread(&bih,1,sizeof(bih),fp);
if(bih.biBitCount != 24 || bih.biCompression != 0)
{
fclose(fp);
return;
}
unsigned char *pBuf = new unsigned char[bih.biSizeImage];
fread(pBuf,bih.biSizeImage,sizeof(unsigned char),fp);
FILE *out = fopen("testout.bmp","wb");
if(!out)
{
delete []pBuf;
fclose(fp);
return;
}
unsigned char *pOutBuf = new unsigned char[bih.biWidth * bih.biHeight];
unsigned char *tmp = pBuf;
unsigned char *tmp2 = pOutBuf;
for(unsigned int i = 0; i < bih.biWidth * bih.biHeight;i++)
{
tmp2[i] = (unsigned char)((*tmp) * .114 + *(tmp + 1) * .587 + *(tmp + 2) * .299);
tmp += 3;
}
RGBQUAD q[256];
for( i = 0; i < 256; i++)
{
q[i].rgbRed = q[i].rgbGreen = q[i].rgbBlue = i;
q[i].rgbReserved = 0;
}
bih.biBitCount = 8;
bih.biSizeImage = bih.biWidth * bih.biHeight;
hdr.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ sizeof(q) + bih.biSizeImage;
hdr.bfOffBits += sizeof(q);
fwrite(&hdr,1,sizeof(hdr),out);
fwrite(&bih,1,sizeof(bih),out);
fwrite(q,256,sizeof(RGBQUAD),out);
fwrite(pOutBuf,bih.biSizeImage,sizeof(unsigned char),out);
delete []pOutBuf;
fclose(out);
delete []pBuf;
fclose(fp);
}