c++bitmap截屏MFC-创新互联

****首先感谢巨人的肩膀,让小白能够走出bitmap图片的苦海。****

成都创新互联是专业的华阴网站建设公司,华阴接单;提供成都网站设计、成都网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行华阴网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

  自己闲的没事想通过c++ 的MFC来截屏并上传服务器展示客户端的当前界面。中间一路降妖伏魔....(此处省略2048个字节),发扬程序猿无私奉献的优良品质,分享源代码来众生同乐。

1.好戏在前头,请在.h添加下面这些东东....

typedef struct _BMPINFO

{

int  bmpWidth;//图像的宽

int  bmpHeight;//图像的高

int  biBitCount;//图像类型,每像素位数

RGBQUAD  pColorTable[256];//颜色表指针

unsigned char pBmpBuf[10240000];

}m_bmpinfo,*p_bmpinfo;

//获取截屏

void getScreen(char* filename);

int readBmp(const char* bmpName, unsigned char* pBmpBuf,int& bmpWidth,int& bmpHeight,int& biBitCount,RGBQUAD *pColorTable);

int sendReadBmp(char* filename,p_bmpinfo bmpinfo);

int recvSaveBmp(char* filename,p_bmpinfo bmpinfo);

int saveBmp(const char* bmpName,unsigned char *pBmpBuf,int& bmpWidth,int& bmpHeight,int& biBitCount,RGBQUAD *pColorTable);

--------------------------累了吧,关了网页休息会--------------------------------------

2.截屏接口,保存截屏(格式为.bmp)到指定路径

in char* filenam:需要保存截屏的文件路径

void getScreen(char* filename)

{

  CDC *pDC;//屏幕DC

  pDC = CDC::FromHandle(GetDC(NULL));//获取当前整个屏幕DC

  int BitPerPixel = pDC->GetDeviceCaps(BITSPIXEL);//获得颜色模式

  int Width = pDC->GetDeviceCaps(HORZRES);

  int Height = pDC->GetDeviceCaps(VERTRES);

  CDC memDC;//内存DC

  memDC.CreateCompatibleDC(pDC);

  CBitmap memBitmap, *oldmemBitmap;//建立和屏幕兼容的bitmap

  memBitmap.CreateCompatibleBitmap(pDC, Width, Height);

  oldmemBitmap = memDC.SelectObject(&memBitmap);//将memBitmap选入内存DC

  memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY);//复制屏幕图像到内存DC

//以下代码保存memDC中的位图到文件

  BITMAP bmp;

  memBitmap.GetBitmap(&bmp);//获得位图信息

  FILE *fp = fopen(filename, "w+b");

  BITMAPINFOHEADER bih = {0};//位图信息头

  bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小

  bih.biCompression = BI_RGB;

  bih.biHeight = bmp.bmHeight;//高度

  bih.biPlanes = 1;

  bih.biSize = sizeof(BITMAPINFOHEADER);

  bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//图像数据大小

  bih.biWidth = bmp.bmWidth;//宽度

  BITMAPFILEHEADER bfh = {0};//位图文件头

  bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量

  bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;//文件总的大小

  bfh.bfType = (WORD)0x4d42;

  fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头

  fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头

  byte * p = new byte[bmp.bmWidthBytes * bmp.bmHeight];//申请内存保存位图数据

  GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject, 0, Height, p,

    (LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据

  fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);//写入位图数据

  delete [] p;

  fclose(fp);

  memDC.SelectObject(oldmemBitmap);

}

--------------------------累了吧,后面没有了--------------------------------------

-----------------------------------------------------------------------------------

3.读取指定位置BMP相关信息到内存中

in const char* bmpName, BMP路径

out unsigned char* pBmpBuf,BMP数据信息

out int& bmpWidth,BMP宽度

out int& bmpHeight,BMP高度

out int& biBitCount,BMP的像素位数

out RGBQUAD *pColorTable色彩版

int readBmp(const char* bmpName, unsigned char* pBmpBuf,int& bmpWidth,int& bmpHeight,int& biBitCount,RGBQUAD *pColorTable)

{

FILE *fp=fopen(bmpName,"rb");

if(fp==0)

{

printf("cannot open file");

return FALSE;

}

fseek(fp,sizeof(BITMAPFILEHEADER),0);

BITMAPINFOHEADER head;

fread(&head,sizeof(BITMAPINFOHEADER),1,fp);

bmpWidth = head.biWidth;

bmpHeight = head.biHeight;

biBitCount = head.biBitCount;

int lineByte = (bmpWidth *biBitCount/8+3)/4*4;//计算图像每行像素所占的字节数

if(biBitCount == 8)

{

pColorTable = new RGBQUAD[256];

fread(pColorTable,sizeof(RGBQUAD),256,fp);

}

fread(pBmpBuf,1,lineByte *bmpHeight,fp);

fclose(fp);

return TRUE;

}

3.1 便于上层调用和重构提供一个封装接口,将所有参数到一个结构体中,可便于socket传输(我4不4很聪明,请叫我少先队员)

in char* filename,BMP路径

out p_bmpinfo bmpinfo BMP数据结构体

int sendReadBmp(char* filename,p_bmpinfo bmpinfo)

{

if(readBmp(filename, bmpinfo->pBmpBuf, bmpinfo->bmpWidth, bmpinfo->bmpHeight, bmpinfo->biBitCount, bmpinfo->pColorTable))

{

return TRUE;

}

return FALSE;

}

--------------------累了吧,么有了------------------------------------------------------

--------------------累了吧,真的么有了----------------------------------------------------

--------------------真的,真的么有了----------------------------------------------------

4.将内存中的BMP数据写入到本地文件

in const char* bmpName, 本地需保存的BMP文件路径

in unsigned char *pBmpBuf,read得到的BMP数据

in int& bmpWidth,BMP宽度

in int& bmpHeight,BMP高度

in int& biBitCount,BMP像素位数

in RGBQUAD *pColorTable调色板

int saveBmp(const char* bmpName,unsigned char *pBmpBuf,int& bmpWidth,int& bmpHeight,int& biBitCount,RGBQUAD *pColorTable)

{

if(!pBmpBuf)//imgBuf 待存盘的位图数据

return 0;

int i,j;

//每行字节数

int lineByte=(bmpWidth*biBitCount/8+3)/4*4;

//循环变量,针对彩×××像,遍历每像素的三个分量

int k;

//将图像左下角1/4部分置成黑色

if(biBitCount==8)

{//对于灰度图像

for(i=0;i

{

for(j=0;j

{

*(pBmpBuf+i*lineByte+j)=0;

}

}

}

else if(biBitCount==24)

{//彩×××像

for(i=0;i

{

for(j=0;j

{

for(k=0;k<3;k++)//每像素RGB三个分量分别置0才变成黑色

*(pBmpBuf+i*lineByte+j*3+k)=0;

}

}

}

int colorTablesize = 0;

if(biBitCount == 8)

colorTablesize = 1024;

FILE *fp = fopen(bmpName,"wb");

if(fp == 0) return 0;

BITMAPFILEHEADER fileHead;

fileHead.bfType= 0x4d42;

fileHead.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) + colorTablesize + lineByte *bmpHeight;

fileHead.bfReserved1 = 0;

fileHead.bfReserved2 = 0;

fileHead.bfOffBits = 54 +colorTablesize;

fwrite(&fileHead,sizeof(BITMAPFILEHEADER),1,fp);

BITMAPINFOHEADER head;

head.biBitCount = biBitCount;

head.biClrImportant = 0;

head.biClrUsed = 0;

head.biCompression = 0;

head.biHeight = bmpHeight;

head.biPlanes =1;

head.biSize = 40;

head.biSizeImage = lineByte *bmpHeight;

head.biWidth = bmpWidth;

head.biXPelsPerMeter = 0;

head.biYPelsPerMeter = 0;

fwrite(&head,sizeof(BITMAPINFOHEADER),1,fp);

if(biBitCount == 8)

fwrite(pColorTable,sizeof(RGBQUAD),256,fp);

fwrite(pBmpBuf,bmpHeight * lineByte,1,fp);

fclose(fp);

return TRUE;

}

4.1 便于socket将接收到的结构体写入本地文件,上层封装了一层,主要与3.1配套使用

int recvSaveBmp(char* filename,p_bmpinfo bmpinfo)

{

saveBmp(filename, bmpinfo->pBmpBuf, bmpinfo->bmpWidth, bmpinfo->bmpHeight, bmpinfo->biBitCount, bmpinfo->pColorTable);

return TRUE;

}

---------------------------------测试代码------------------------------------------------
发送端:

p_bmpinfo bmpinfo = (p_bmpinfo)malloc(sizeof(m_bmpinfo));

sendReadBmp(sFileName,bmpinfo);

socketSend(client,(char*)bmpinfo,sizeof(m_bmpinfo));//socket发送

接收端:

p_bmpinfo bmpinfo = (p_bmpinfo)malloc(sizeof(m_bmpinfo));

int len;

SOCKET socket = socketAccept(server); //socket监听

do {

len = socketRecv(socket,(char*)bmpinfo,sizeof(m_bmpinfo));//socket接受数据

recvSaveBmp(sFileName,bmpinfo);

} while(0 != len);

--------------------------------么有了,木骗你------------------------------------

--------------------------------么有了,俺真木骗你------------------------------------

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章标题:c++bitmap截屏MFC-创新互联
文章URL:http://myzitong.com/article/cdpscj.html