****首先感谢巨人的肩膀,让小白能够走出bitmap图片的苦海。****
10多年的交口网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都营销网站建设的优势是能够根据用户设备显示端的尺寸不同,自动调整交口建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联从事“交口网站设计”,“交口网站推广”以来,每个客户项目都认真落实执行。
自己闲的没事想通过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); --------------------------------么有了,木骗你------------------------------------ --------------------------------么有了,俺真木骗你------------------------------------
发送端:
本文名称:c++bitmap截屏MFC
链接分享:http://njwzjz.com/article/jegcoh.html