位图操作集合

来源:互联网 发布:mac 视频软件 知乎 编辑:程序博客网 时间:2024/06/05 11:03

一、 显示位图

在Visual C++6.0中,显示位图的方法及过程如下: 
1. 显示程序资源中的位图(位图的所有数据均存在于可执行文件中) 
(1)从资源中装入位图

 ● 定义位图对象数据成员CBitmap m_Bitmap; 
 ● 调用CBitmap成员函数LoadBitmap(),如m_Bitmap.LoadBitmap(IDB_BITMAP1); 
 ● 传入LoadBitmap的参数是位图在图形编辑器中生成或从位图文件中引入时赋予的识别符。
(2)生成与位图相联系的内存设备情境对象

CDC MemDC; MemDC.CreateCompatibleDC(NULL); MemDC.SelectObject(&m_Bitmap); 

(3)显示位图

CClientDC ClientDC(this); BITMAP BM; m_Bitmap.GetObject(sizeof(BM),&BM); ClientDC.BitBlt ( X,Y, //目标设备逻辑横、纵坐标 BM.bmWidth, BM.bmHeight, //显示位图的像素宽、高度 &MemDC,//待显示位图数据的设备情境对象 0,0, //源数据中的横、纵坐标SRCCOPY); //位操作方式

这种方法显示位图速度快,但不是很灵活,而且会使可执行文件增大。
2. 显示独立文件方式的位图(位图的所有数据独立于可执行文件)        

HBITMAP *hBitmap; //定义位图对象句柄 BITMAP BM; CDC MemDC; CClientDC ClientDC(this); MemDC.CreateCompatibleDC(&ClientDC); hBitmap=(HBITMAP*):: LoadImage ( AfxGetInstanceHandle(), //取得应用程序句柄 “demo1.bmp”, //位图文件名 IMAGE_BITMAP, //类型为Windows位图 0,0, LR_LOADFROMFILE); //从文件中取位图数据 MemDC.SelectObject(hBitmap); :: GetObject(hBitmap,sizeof(BM),&BM); ClientDC.BitBlt(……) //使用格式与方法一同

这种方法显示位图速度较之前一种慢了一点,但其灵活性较大,可以任意变换位图文件,而无需重新编译源程序, 也减小了可执行文件的大小。

二、保存位图       

       CString m_Path("C:\\");       int       nX, nY, nX2, nY2;  // 选定区域坐标              int       Width, Height;              // 确保选定区域不为空矩形       if (IsRectEmpty(lpRect))              return NULL;       // 获得选定区域坐标       nX = lpRect->left;       nY = lpRect->top;       nX2 = lpRect->right;       nY2 = lpRect->bottom;       //确保选定区域是可见的       if (nX < 0)              nX = 0;       if (nY < 0)              nY = 0;       if (nX2 > m_xScreen)              nX2 = m_xScreen;       if (nY2 > m_yScreen)              nY2 = m_yScreen;       Width = nX2 - nX;       Height = nY2 - nY;      CDC dc;      dc.CreateDC("DISPLAY",NULL,NULL,NULL);      CBitmap bm;       bm.CreateCompatibleBitmap(&dc,Width,Height);       CDC tdc;       tdc.CreateCompatibleDC(&dc);       CBitmap*pOld=tdc.SelectObject(&bm);       tdc.BitBlt(0,0,Width,Height,&dc,nX,nY,SRCCOPY);       tdc.SelectObject(pOld);       BITMAP btm;       bm.GetBitmap(&btm);              DWORD size=btm.bmWidthBytes*btm.bmHeight;       LPSTR lpData=(LPSTR)GlobalAllocPtr(GPTR,size);/////////////////////////////////////////////       BITMAPINFOHEADER bih;       bih.biBitCount=btm.bmBitsPixel;       bih.biClrImportant=0;       bih.biClrUsed=0;       bih.biCompression=0;       bih.biHeight=btm.bmHeight;       bih.biPlanes=1;       bih.biSize=sizeof(BITMAPINFOHEADER);       bih.biSizeImage=size;       bih.biWidth=btm.bmWidth;       bih.biXPelsPerMeter=0;       bih.biYPelsPerMeter=0;///////////////////////////////////       GetDIBits(dc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);//     bm.GetBitmapBits(size,lpData);     //此函数在处理5-5-5模式的16位色下会出现颜色混乱//////////////////////////////       static int filecount=0;       CString name;       name.Format("pict%04d.bmp",filecount++);       name=m_Path+name;              MessageBox(name);       BITMAPFILEHEADER bfh;       bfh.bfReserved1=bfh.bfReserved2=0;       bfh.bfType=((WORD)(''M''<< 8)|''B'');       bfh.bfSize=54+size;       bfh.bfOffBits=54;       CFile bf;       if(bf.Open(name,CFile::modeCreate|CFile::modeWrite)){              bf.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER));              bf.WriteHuge(&bih,sizeof(BITMAPINFOHEADER));              bf.WriteHuge(lpData,size);              bf.Close();              }       GlobalFreePtr(lpData);

三、32位位图到24位位图的转换

在图像处理的很多实际应用中,我们需要对图像的颜色表示进行转换(如,将32位颜色转换到24位颜色等等)。本文通过一个简单的例子,说明了32位颜色到24位颜色的转换过程。程序假设当前windows桌面颜色为32位颜色值。
(一)功能
在图像处理的很多实际应用中,我们需要对图像的颜色表示进行转换(如,将32位颜色转换到24位颜色等等)。本文通过一个简单的例子,说明了32位颜色到24位颜色的转换过程。程序假设当前windows桌面颜色为32位颜色值。 
(二)准备工作
建立VC CONSOLE APPLICATION,选择MFC SUPPORT
(三)主函数
函数Bmp32ToBmp24将32位位图转换到24位位图格式。
注意:该函数假设当前windows桌面颜色为32位颜色值。
// transform 32-bit bitmap format to 24-bit bitmap format void Bmp32ToBmp24(char Filename[]){char Filename2[] = "output.bmp";//注意:如果没有LR_CREATEDIBSECTION,位图颜色将被映射到屏幕DC颜色//也就是说,如果屏幕是16位颜色,则所有的图像都将映射到16位颜色HBITMAP hbmp32 = (HBITMAP) LoadImage(NULL, Filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);BITMAP bmp;//获取位图信息GetObject(hbmp32, sizeof(BITMAP), &bmp);printf("Image Bit Depth : %d\nWidth : %d , Height : %d \n", bmp.bmBitsPixel, bmp.bmWidth, bmp.bmHeight);//显示位图颜色模式和图像宽高//计算24位图像每行的字节数int BytesPerLine = 3 * bmp.bmWidth;while(BytesPerLine % 4 != 0)BytesPerLine ++;BITMAPINFOHEADER bih = {0};//位图信息头bih.biBitCount = 24;//每个像素字节大小bih.biCompression = BI_RGB;bih.biHeight = bmp.bmHeight;//高度bih.biPlanes = 1;bih.biSize = sizeof(BITMAPINFOHEADER);bih.biSizeImage = BytesPerLine * bmp.bmHeight;//图像数据大小bih.biWidth = bmp.bmWidth;//宽度BITMAPFILEHEADER bfh = {0};//位图文件头bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量bfh.bfSize = bfh.bfOffBits + bih.biSizeImage;//文件总的大小bfh.bfType = (WORD)0x4d42;FILE *fp = fopen(Filename2, "w+b");fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头byte * p = new byte[bih.biSizeImage];//获取当前32位图像数据GetDIBits(GetDC(NULL), hbmp32, 0, bmp.bmHeight, p, (LPBITMAPINFO)&bih, DIB_RGB_COLORS);//只取rgb值,存入文件byte b = 0;//用于填充for(int i = 0 ; i < bmp.bmWidth * bmp.bmHeight ; i ++){//32位位图图像的格式为:Blue, Green, Red, Alphafwrite(&(p[i * 3]), 1, 3, fp);if(i % bmp.bmWidth == bmp.bmWidth - 1)//填充字节{   for(int k = 0 ; k < (BytesPerLine - bmp.bmWidth * 3) ; k ++)    fwrite(&b, sizeof(byte), 1, fp);}}delete [] p;fclose(fp);DeleteObject(hbmp32);}