教你个方法,
1.双缓冲知道吧,就是在内存中建立快画布。
将这个在内存方步中曲线画出来,
ScrBmp=CreateCompatibleBitmap(pDC->m_hDC,rect.Width(),rect.Height());//创建兼容的位图
HBITMAP old=(HBITMAP)SelectObject(m_MemDC->m_hDC,ScrBmp);//选入位图
画图操作
2.
bool CCopyScreenDlg::SaveBmpToFile(LPCSTR lpFileName,HBITMAP hBitmap)
{
//lpFileName 为位图文件名
HDC hDC;
//设备描述表
int iBits;
//当前显示分辨率下每个像素所占字节数
WORD wBitCount;
//位图中每个像素所占字节数
//定义调色板大小, 位图中像素字节大小 , 位图文件大小 , 写入文件字节数
DWORD dwPaletteSize=0,dwBmBitsSize,dwDIBSize, dwWritten;
BITMAP Bitmap;
BITMAPFILEHEADER bmfHdr; //位图属性结构
BITMAPINFOHEADER bi; //位图文件头结构
//位图信息头结构
LPBITMAPINFOHEADER lpbi;
//指向位图信息头结构
HANDLE fh, hDib, hPal;
HPALETTE hOldPal=NULL; //定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
iBits=24;
if (iBits<=1) wBitCount=1;
else if (iBits<=4 ) wBitCount =4;
else if (iBits<=8 ) wBitCount =8;
else if (iBits<=32) wBitCount =24;
//计算调色板大小
if (wBitCount<=8) dwPaletteSize=(1<<wBitCount)*sizeof(RGBQUAD);
//设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP),(LPSTR)&Bitmap);
bi.biSize=sizeof(BITMAPINFOHEADER);
bi.biWidth=Bitmap.bmWidth;
bi.biHeight=Bitmap.bmHeight;
bi.biPlanes=1;
bi.biBitCount= wBitCount;
bi.biCompression=BI_RGB;
bi.biSizeImage=0;
bi.biXPelsPerMeter= 0;
bi.biYPelsPerMeter= 0;
bi.biClrUsed=0;
bi.biClrImportant=0;
dwBmBitsSize= ((Bitmap.bmWidth*wBitCount+31)/32)*4*Bitmap.bmHeight;
//为位图内容分配内存
hDib =GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
lpbi =(LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi=bi;
//处理调色板
hPal=GetStockObject(DEFAULT_PALETTE);
if(hPal)
{
hDC=GetDC()->GetSafeHdc();
hOldPal=SelectPalette(hDC,(HPALETTE)hPal,FALSE);
RealizePalette(hDC);
}
//获取该调色板下新的像素值
GetDIBits(hDC,hBitmap,0,(UINT)Bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwPaletteSize,(BITMAPINFO *)lpbi,DIB_RGB_COLORS);
//恢复调色板
if(hOldPal)
{
SelectPalette(hDC,hOldPal,TRUE);
RealizePalette(hDC);
}
//创建位图文件
fh=CreateFile(lpFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if (fh==INVALID_HANDLE_VALUE) return FALSE;
//设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize;
bmfHdr.bfSize= dwDIBSize;
bmfHdr.bfReserved1=0;
bmfHdr.bfReserved2=0;
bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwPaletteSize;
//写入位图文件头
WriteFile(fh,(LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER), &dwWritten,NULL);
//写入位图文件其余内容
WriteFile(fh,(LPSTR)lpbi,dwDIBSize,&dwWritten,NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);
return TRUE;
}
方法2:
BITMAP BitMap;
BitMap.bmType=0;
BitMap.bmHeight=320;
BitMap.bmWidth=240;
BitMap.bmWidthBytes=240*4;//大于或等于bmWidth*bmBitsPixel/8所得的值
BitMap.bmPlanes=1;
BitMap.bmBitsPixel=32;//32位的位图
BitMap.bmBits=rgbData;//二位数组320*240的二维数组
CBitmap cbitMap;
cbitMap.CreateBitmapIndirect(&BitMap);
然后保存
追问看着有点晕,二维数组转换成1维的那一步呢?这个需要双缓冲吗?
追答2维数组转化为一维你不会?首先你的二位数组是图片的大小:
arr[640][480*3];全部出初始化0(24位图片),比如第一点需要画出来
arr[0][0]=255;
arr[0][1]=255;
arr[0][2]=255;
一次类推,背景为黑色,点为白色
然后定义一个为数组arr[640*480*3];
将二位数组通过循环方式复制。
追问但是老师说的是转换成y*width+x,这样的啊,怎么越看越复杂了。。
追答8位位图的就是你老师要求的格式了,大哥。
byte arr[640*480];
读文件赋值
arr[y*width+x]=255;
追问大哥,麻烦你把中间加程序那帮我写下吧,然后我再仔细看,谢谢啊
追答你把程序和数据发给我,[email protected]