VC++ 导出bmp图片

来源:互联网 发布:手机投影电脑软件 编辑:程序博客网 时间:2024/05/18 09:22

我们经常遇到这种情况,就是需要把当前桌面的指定区域大小保存为图片以供以后使用,类似于QQ的截图工具。

其实方法很简单,就是创建与指定设备兼容的内存设备上下文环境(DC),然后创建与指定的设备环境相关的设备兼容的位图,接着把这个设备兼容的位图选入到设备兼容的内存中。最后就是将这个位图导出即可。

不过在此之前需要了解一下两个知识点:一个是如何创建和使用与指定设备兼容的内存设备上下文环境,二是如何将位图导出为本地图片

1.与指定设备兼容的内存设备上下文环境(双缓冲)

HDC CreateCompatibleDC(HDC hdc);

平常我们在使用GetDC获取HDC直接与相关设备沟通,比如在一个对话框对应的类中直接使用GetDC获取的HDC就是直接与这个对话框相关联,而我们在这获取的设备兼容得到的HDC是和内存中的一个表面想关联。

内存设备上下文环境是仅在内存中存在的设备上下文环境,当内存中设备上下文被创建时,它的显示标准是一个单色像素宽和一个单色像素高,当一个应用程序使用设备上下文环境进行绘图之前,它必须选定一个高和宽都正确设定的位图到设备上下文环境中,这里可以使用CreateCompatibleBitmap函数指定高、宽和色彩组合以指定函数调用的需要来创建位图。实例:

CBitmap bitmap;CDC dcMemSave;dcMemSave.CreateCompatibleDC(NULL);CDC *pDC = GetDC();bitmap.CreateCompatibleBitmap(pDC,m_PaintRect.right-m_PaintRect.left,m_PaintRect.bottom-m_PaintRect.top);dcMemSave.SelectObject(&bitmap);dcMemSave.BitBlt(0,0,m_PaintRect.right-m_PaintRect.left,m_PaintRect.bottom-m_PaintRect.top,pDC,m_PaintRect.left,m_PaintRect.top,SRCCOPY);HBITMAP hBmp = (HBITMAP)bitmap;SaveBMP(hBmp); //保存位图到本地DeleteObject(bitmap);

CreateCompatibleDc函数只适用于支持光栅操作的设备,应用程序可以通过调用GetDeviceCaps函数来确定一个设备是否支持这些操作。当不再需要内存设备上下文环境时,可调用DeleteDc函数删除它。

2.将bmp保存到本地bmp图片

BMP是一种与硬件设备无关的图像文件格式,使用非常广。由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。典型的BMP图像文件由三部分组成:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;

位图文件头(bitmap-file header)                                                                     

所用结构:
BITMAPFILEHEADER                                                     包含了图像类型、图像大小、图像数据存放地址和两个保留未使用的字段

位图信息头(bitmap-information header)                                                                                                        

所用结构:BITMAPINFOHEADER包含了位图信息头的大小、图像的宽高、图像的色深、压缩说明图像数据的大小和其他一些参数

彩色表/调色板(color table)

RGBQUAD颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,24色位图没有颜色表项,位图信息头BITMAPINFOHEADER和颜色表RGBQUAD组成位图信息BITMAPINFO

位图数据(bitmap-data)

char*位图数据信息HBITMAP格式
导出图片源码如下:

bool CDotChart::SaveBMP(HBITMAP &map){OpenFileDialog(m_hWnd);if(GetSaveFileName(&ofn)){wsprintf(filepath,"%s",ofn.lpstrFile);}else{return false;}//把位图的信息保存到bmpinfoBITMAP bmpinfo;GetObject(map,sizeof(BITMAP),&bmpinfo);DWORD dwBmBitsSize = ((bmpinfo.bmWidth * 32+31)/32) * 4 * bmpinfo.bmHeight; //位图文件头 14字节BITMAPFILEHEADER bf;bf.bfType      = 0x4D42;                  //BMbf.bfSize      = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize; bf.bfReserved1 = 0; bf.bfReserved2 = 0; bf.bfOffBits   = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); //位图信息头BITMAPINFOHEADER bi;bi.biSize          = sizeof(BITMAPINFOHEADER);bi.biWidth         = bmpinfo.bmWidth;bi.biHeight        = bmpinfo.bmHeight;bi.biPlanes        = 1;bi.biBitCount      = 32;bi.biCompression   = BI_RGB;bi.biSizeImage     = 0;bi.biXPelsPerMeter = 0;bi.biYPelsPerMeter = 0;bi.biClrUsed       = 8;bi.biClrImportant  = 0;//颜色表由红、绿、蓝(RGB)三个直接值构成//调用GetDIBits直接绘制设备无关图,并复制到缓冲区中char* context = new char[dwBmBitsSize];HDC dc  = ::GetDC(NULL);GetDIBits(dc, map, 0, bi.biHeight, context, (BITMAPINFO*)&bi, DIB_RGB_COLORS);//写位图到本地图片HANDLE file = ::CreateFile(filepath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);DWORD Num;if(INVALID_HANDLE_VALUE != file ){WriteFile(file,&bf,sizeof(BITMAPFILEHEADER),&Num,NULL);WriteFile(file,&bi,sizeof(BITMAPINFOHEADER),&Num,NULL);WriteFile(file,context,dwBmBitsSize,&Num,NULL);::CloseHandle(file);}delete context;return 0;}bool CDotChart::OpenFileDialog(HWND hWnd){char szFile[260]; // 用于文件名的缓冲区      // 初始化OPENFILENAME ZeroMemory(&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.lpstrTitle = "另存为";ofn.lpstrFile = szFile;ofn.hwndOwner = hWnd;      ofn.nMaxFile = sizeof(szFile); ofn.lpstrFilter = TEXT("图片文件(*.bmp)\0*.bmp\0所有文件(*.*)\0*.*\0");ofn.lpstrDefExt = "*.bmp";ofn.nFilterIndex = 1; ofn.lpstrFileTitle = "NULL"; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;return 0;}


原创粉丝点击