您好,登錄后才能下訂單哦!
****首先感謝巨人的肩膀,讓小白能夠走出bitmap圖片的苦海。****
自己閑的沒事想通過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<bmpHeight/2;i++)
{
for(j=0;j<bmpWidth/2;j++)
{
*(pBmpBuf+i*lineByte+j)=0;
}
}
}
else if(biBitCount==24)
{//彩×××像
for(i=0;i<bmpHeight/2;i++)
{
for(j=0;j<bmpWidth/2;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);
--------------------------------么有了,木騙你------------------------------------
--------------------------------么有了,俺真木騙你------------------------------------
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。