Bitmap位图文件读取、保存、屏幕截图
2014-01-23 10:25
405 查看
虽然现在网上已经有很多位图读取、保存的文章,很多写的都很详细,提供的源代码功能也很强大,但是我仍然要自己重写一个位图加载程序。主要是因为这些大牛们的文章写的太深奥了,代码功能太强大了,以至于像我这样的菜鸟读不懂。所以,我要力求简洁。省略掉一些细节,比方说调色板。为了能够方便容易操作,我的程序只支持24位以上的位图文件加载。
首先,了解下位图文件的结构。24位以上的位图文件包含3个部分:位图文件头(BITMAPFILEHEADER)、位图信息头(BITMAPINFOHEADER)、位图数据。
下面是MSDN中两个信息头的具体定义:
[cpp] view
plaincopy
typedef struct tagBITMAPFILEHEADER {
WORD bfType; //图像类型:必须是‘BM’(BM的16进制编码为:0x4d42)
DWORD bfSize; //位图文件大小。
WORD bfReserved1; //保留值。必须为0
WORD bfReserved2; //保留值。必须为0
DWORD bfOffBits; //从文件开头到像素数据的偏移量。
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; //当前结构体的大小。
LONG biWidth; //位图的宽度。单位是像素
LONG biHeight; //位图高度。单位是像素
WORD biPlanes; //位图平面个数。必须是1
WORD biBitCount //位图的位数,也就是位图深度。可以是1、4、8、16、24、32。16位以下的位图文件含有调色板信息。
DWORD biCompression; //压缩方式。位图没有压缩,赋予BI_RGB参数(也就是0)。
DWORD biSizeImage; //位图数据占用的字节数。可以设置为默认值0。
LONG biXPelsPerMeter; //指定目标设备水平分辨率,单位是每米的像素个数。可设置为0
LONG biYPelsPerMeter; //指定目标设备垂直分辨率,同上。
DWORD biClrUsed; //指定本图像实际用到的像素。可设置为0
DWORD biClrImportant; //指定本图像重要的颜色个数。可设置为0,表示所有颜色都重要。
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
接下来就是位图数据了:
位图按行存贮,位图的宽度不等于位图的行字节数。每个像素占用 biBitCount/8 个字节,且每行占用的字节数必须是4字节的整数倍!例如:101*101*24的位图,行占用字节数为:101*3=303,而303%4!=0,所以行占用字节数需修改为304,此时位图数据的实际大小为304*101,上面的biSizeImage就可设置为304*101。
下面是保存位图文件的结构体填充例:
[cpp] view
plaincopy
BITMAPFILEHEADER bmheader;
memset(&bmheader,0,sizeof(bmheader));
bmheader.bfType=0x4d42; //图像格式。必须为'BM'格式。
bmheader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); //从文件开头到数据的偏移量
bmheader.bfSize = m_nWidthBytes*m_nHeight + bmheader.bfOffBits;//文件大小
BITMAPINFOHEADER bmInfo;
memset(&bmInfo,0,sizeof(bmInfo));
bmInfo.biSize = sizeof(bmInfo);
bmInfo.biWidth = m_nWidth;
bmInfo.biHeight = m_nHeight;
bmInfo.biPlanes = 1;
bmInfo.biBitCount = m_nDeep;
bmInfo.biCompression = BI_RGB;
注:m_nWidthBytes 可这样计算:int m_nWidthBytes = ((m_nWidth*m_nDeep/8 + 3)/4) * 4;
下面是一个用来创建DIB位图,获得HBITMAP句柄一个API。
大致说下打开文件文件的流程:
1.读入文件头BITMAPFILEHEADER数据。
2.读入位图信息头BITMAPINFOHEADER数据。
3.读取位图数据。
4.使用CreateDIBSection创建Dib位图,将读取到的数据拷贝给Dib位图。
然后就可以使用Dib位图句柄进行位图的操作了。
保存文件流程:
1.填写文件头BITMAPFILEHEADER,并写入文件。
2.填写位图信息头BITMAPINFOHEADER,并写入文件。
3.获得位图数据(GetBitmapBits,或者是在CreateDIBSection时,将数据地址记录下来),将数据写入文件。
截图功能(参考样例见文章末尾):
1.创建掩码DC(CreateCompatibelDC),掩码位图(CreateCompatibleBitmap),将位图选到DC中。
2.将 要截图的窗口的DC内容拷贝(BitBlt)给掩码DC(也就是拷贝到了掩码位图上了)。
3.接着就是上面说到的保存文件流程了。
附件:我将上面的操作封装起来。
[cpp] view
plaincopy
//DIBBitmap.h
#pragma once
class CDIBBitmap
{
public://方法
CDIBBitmap(void);
~CDIBBitmap(void);
bool create(HDC hdc,int width,int height,int deep);//创建位图
bool create(HDC hDC,HBITMAP hBitmap);//通过拷贝来创建位图
bool load(HDC hDC,char *szFileName);//从文件中价值位图
bool save(char *szFileName);//保存位图到文件
void clear(void);//清空数据
void sampleRender(HDC hDC,int x,int y);//简单显示
public://属性
//获得位图
inline HBITMAP getBitmap(void){ return m_hDibBmp; }
//获得数据
inline BYTE * getBmpData(void){ return m_pBmpData; }
//获得宽度
inline int getWidth(void){ return m_nWidth; }
//获得高度
inline int getHeight(void){ return m_nHeight; }
//获得位深度
inline int getDeep(void){ return m_nDeep; }
//获得一行字节数
inline int getWidthBytes(void){ return m_nWidthBytes; }
protected://成员
HBITMAP m_hDibBmp;
BYTE *m_pBmpData;//指向位图数据
int m_nWidth; //宽度。(单位:像素pixel)
int m_nHeight; //高度。pixel
int m_nDeep; //深度。bit。深度必须大于24位
int m_nWidthBytes;//一行所需的字节数。必须是4字节的整数倍。
};
[cpp] view
plaincopy
#include <Windows.h>
#include <stdio.h>
#include <cassert>
#include "DIBBitmap.h"
class FileHoder
{
FILE *m_pFile;
public:
FileHoder(FILE *pFile)
: m_pFile(pFile)
{}
~FileHoder()
{
if (m_pFile) fclose(m_pFile);
}
};
//////////////////////////////////////////////////////////////////////////
CDIBBitmap::CDIBBitmap(void)
{
m_hDibBmp = NULL;
m_pBmpData = NULL;
m_nWidth = 0; //宽度。(单位:像素pixel)
m_nHeight = 0; //高度。pixel
m_nDeep = 0; //深度。bit。深度必须大于24位
m_nWidthBytes = 0;
}
CDIBBitmap::~CDIBBitmap(void)
{
clear();
}
bool CDIBBitmap::create(HDC hdc, int width, int height, int deep)
{
clear();
m_nWidth = width;
m_nHeight = height;
m_nDeep = deep;
m_nWidthBytes = ((m_nWidth*m_nDeep / 8 + 3) / 4) * 4;
m_pBmpData = nullptr;
BITMAPINFO bmInfo;
memset(&bmInfo, 0, sizeof(bmInfo));
bmInfo.bmiHeader.biSize = sizeof(bmInfo);
bmInfo.bmiHeader.biWidth = m_nWidth;
bmInfo.bmiHeader.biHeight = m_nHeight;
bmInfo.bmiHeader.biPlanes = 1;
bmInfo.bmiHeader.biBitCount = m_nDeep;
bmInfo.bmiHeader.biCompression = BI_RGB;
//如果创建成功,m_pBmpData将指向位图的像素区域。
m_hDibBmp = CreateDIBSection(hdc, &bmInfo, DIB_RGB_COLORS, (void**) &m_pBmpData, NULL, 0);
if (m_hDibBmp == NULL)
{
return false;
}
return true;
}
bool CDIBBitmap::create(HDC hDC, HBITMAP hBitmap)
{
if (NULL == hDC || NULL == hBitmap)
{
return false;
}
//获得位图信息
BITMAP bm;
GetObject(hBitmap, sizeof(bm), &bm);
//创建位图
if (!create(hDC, bm.bmWidth, bm.bmHeight, bm.bmBitsPixel))
{
return false;
}
//获得hBitmap数据,并拷贝给Dib位图
GetBitmapBits(hBitmap, bm.bmWidthBytes*bm.bmHeight, getBmpData());
return true;
}
void CDIBBitmap::clear(void)
{
if (m_hDibBmp != NULL)
{
DeleteObject(m_hDibBmp);
}
m_hDibBmp = NULL;
m_pBmpData = NULL;
}
void CDIBBitmap::sampleRender(HDC hDC, int x, int y)
{
if (!m_hDibBmp) return;
 
1d831
;
HDC memDC = CreateCompatibleDC(0);
SelectObject(memDC, m_hDibBmp);
BitBlt(hDC, x, y, m_nWidth, m_nHeight, memDC, 0, 0, SRCCOPY);
DeleteDC(memDC);
}
bool CDIBBitmap::load(HDC hDC, char *szFileName)
{
assert(hDC && szFileName && "CDIBBitmap::load");
FILE *fp = NULL;
fopen_s(&fp, szFileName, "rb");
if (NULL == fp)
{
return false;
}
FileHoder holder(fp);
//读入文件头
BITMAPFILEHEADER bmheader;
if (fread(&bmheader, sizeof(bmheader), 1, fp) != 1)
{
return false;
}
//无效的位图文件
if (bmheader.bfType != 0x4d42)
{
return false;
}
//读入位图信息头
BITMAPINFOHEADER bmInfo;
if (fread(&bmInfo, sizeof(bmInfo), 1, fp) != 1)
{
return false;
}
//注:目前程序不支持调色板数据位图加载。
if (bmInfo.biBitCount < 16)
{
return false;
}
//创建DIB位图
if (!create(hDC, bmInfo.biWidth, bmInfo.biHeight, bmInfo.biBitCount))
{
return false;
}
//定位到像素数据
fseek(fp, bmheader.bfOffBits, SEEK_SET);
//读入像素数据
if (fread(m_pBmpData, m_nWidthBytes, m_nHeight, fp) != m_nHeight)
{
return false;
}
return true;
}
bool CDIBBitmap::save(char *szFileName)
{
assert(szFileName && "CDIBBitmap::save");
if (NULL == m_hDibBmp || NULL == m_pBmpData)
{
return false;
}
FILE *fp = NULL;
fopen_s(&fp, szFileName, "wb");
if (NULL == fp)
{
return false;
}
FileHoder hoder(fp);
BITMAPFILEHEADER bmheader;
memset(&bmheader, 0, sizeof(bmheader));
bmheader.bfType = 0x4d42; //图像格式。必须为'BM'格式。
bmheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); //从文件开头到数据的偏移量
bmheader.bfSize = m_nWidthBytes*m_nHeight + bmheader.bfOffBits;//文件大小
BITMAPINFOHEADER bmInfo;
memset(&bmInfo, 0, sizeof(bmInfo));
bmInfo.biSize = sizeof(bmInfo);
bmInfo.biWidth = m_nWidth;
bmInfo.biHeight = m_nHeight;
bmInfo.biPlanes = 1;
bmInfo.biBitCount = m_nDeep;
bmInfo.biCompression = BI_RGB;
fwrite(&bmheader, sizeof(bmheader), 1, fp);
fwrite(&bmInfo, sizeof(bmInfo), 1, fp);
for (int i = 0; i < m_nHeight; ++i)
{
int index = m_nWidthBytes*i;
fwrite(m_pBmpData + index, m_nWidthBytes, 1, fp);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
截图功能参考代码:
[cpp] view
plaincopy
//获得设备描述表
m_hDeviceContext=GetDC(m_hWnd);
//创建掩码dc
m_hBackDC=CreateCompatibleDC(m_hDeviceContext);
//创建掩码位图
m_bBackBitmap=CreateCompatibleBitmap(m_hDeviceContext,m_nWidth,m_nHeight);
SelectObject(m_hBackDC,m_bBackBitmap);
...
将m_hDeviceContext的内容使用BitBlt拷贝给m_hBackDC
...
CDIBBitmap bmp;
if(!bmp.create(m_hBackDC,m_bBackBitmap))
{
g_log.write("截图失败!");
}
else
{
CreateDirectory(TEXT("shot"),NULL);
char buffer[64];
SYSTEMTIME tm;
GetLocalTime(&tm);
sprintf_s(buffer,64,"shot/%d_%d_%d_%d_%d_%d.bmp",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
if(!bmp.save(buffer))
{
g_log.writex("保存位图【%s】失败!",buffer);
}
}
首先,了解下位图文件的结构。24位以上的位图文件包含3个部分:位图文件头(BITMAPFILEHEADER)、位图信息头(BITMAPINFOHEADER)、位图数据。
下面是MSDN中两个信息头的具体定义:
[cpp] view
plaincopy
typedef struct tagBITMAPFILEHEADER {
WORD bfType; //图像类型:必须是‘BM’(BM的16进制编码为:0x4d42)
DWORD bfSize; //位图文件大小。
WORD bfReserved1; //保留值。必须为0
WORD bfReserved2; //保留值。必须为0
DWORD bfOffBits; //从文件开头到像素数据的偏移量。
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; //当前结构体的大小。
LONG biWidth; //位图的宽度。单位是像素
LONG biHeight; //位图高度。单位是像素
WORD biPlanes; //位图平面个数。必须是1
WORD biBitCount //位图的位数,也就是位图深度。可以是1、4、8、16、24、32。16位以下的位图文件含有调色板信息。
DWORD biCompression; //压缩方式。位图没有压缩,赋予BI_RGB参数(也就是0)。
DWORD biSizeImage; //位图数据占用的字节数。可以设置为默认值0。
LONG biXPelsPerMeter; //指定目标设备水平分辨率,单位是每米的像素个数。可设置为0
LONG biYPelsPerMeter; //指定目标设备垂直分辨率,同上。
DWORD biClrUsed; //指定本图像实际用到的像素。可设置为0
DWORD biClrImportant; //指定本图像重要的颜色个数。可设置为0,表示所有颜色都重要。
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
接下来就是位图数据了:
位图按行存贮,位图的宽度不等于位图的行字节数。每个像素占用 biBitCount/8 个字节,且每行占用的字节数必须是4字节的整数倍!例如:101*101*24的位图,行占用字节数为:101*3=303,而303%4!=0,所以行占用字节数需修改为304,此时位图数据的实际大小为304*101,上面的biSizeImage就可设置为304*101。
下面是保存位图文件的结构体填充例:
[cpp] view
plaincopy
BITMAPFILEHEADER bmheader;
memset(&bmheader,0,sizeof(bmheader));
bmheader.bfType=0x4d42; //图像格式。必须为'BM'格式。
bmheader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); //从文件开头到数据的偏移量
bmheader.bfSize = m_nWidthBytes*m_nHeight + bmheader.bfOffBits;//文件大小
BITMAPINFOHEADER bmInfo;
memset(&bmInfo,0,sizeof(bmInfo));
bmInfo.biSize = sizeof(bmInfo);
bmInfo.biWidth = m_nWidth;
bmInfo.biHeight = m_nHeight;
bmInfo.biPlanes = 1;
bmInfo.biBitCount = m_nDeep;
bmInfo.biCompression = BI_RGB;
注:m_nWidthBytes 可这样计算:int m_nWidthBytes = ((m_nWidth*m_nDeep/8 + 3)/4) * 4;
下面是一个用来创建DIB位图,获得HBITMAP句柄一个API。
HBITMAP CreateDIBSection(
HDC hdc, // handle to DC
CONST BITMAPINFO *pbmi, // bitmap data
UINT iUsage, // data type indicator
VOID **ppvBits, // bit values
HANDLE hSection, // handle to file mapping object
DWORD dwOffset // offset to bitmap bit values
);(这里就不详细介绍了,可以去百科里看看,如:http://www.hudong.com/wiki/CreateDIBSection)
大致说下打开文件文件的流程:
1.读入文件头BITMAPFILEHEADER数据。
2.读入位图信息头BITMAPINFOHEADER数据。
3.读取位图数据。
4.使用CreateDIBSection创建Dib位图,将读取到的数据拷贝给Dib位图。
然后就可以使用Dib位图句柄进行位图的操作了。
保存文件流程:
1.填写文件头BITMAPFILEHEADER,并写入文件。
2.填写位图信息头BITMAPINFOHEADER,并写入文件。
3.获得位图数据(GetBitmapBits,或者是在CreateDIBSection时,将数据地址记录下来),将数据写入文件。
截图功能(参考样例见文章末尾):
1.创建掩码DC(CreateCompatibelDC),掩码位图(CreateCompatibleBitmap),将位图选到DC中。
2.将 要截图的窗口的DC内容拷贝(BitBlt)给掩码DC(也就是拷贝到了掩码位图上了)。
3.接着就是上面说到的保存文件流程了。
附件:我将上面的操作封装起来。
[cpp] view
plaincopy
//DIBBitmap.h
#pragma once
class CDIBBitmap
{
public://方法
CDIBBitmap(void);
~CDIBBitmap(void);
bool create(HDC hdc,int width,int height,int deep);//创建位图
bool create(HDC hDC,HBITMAP hBitmap);//通过拷贝来创建位图
bool load(HDC hDC,char *szFileName);//从文件中价值位图
bool save(char *szFileName);//保存位图到文件
void clear(void);//清空数据
void sampleRender(HDC hDC,int x,int y);//简单显示
public://属性
//获得位图
inline HBITMAP getBitmap(void){ return m_hDibBmp; }
//获得数据
inline BYTE * getBmpData(void){ return m_pBmpData; }
//获得宽度
inline int getWidth(void){ return m_nWidth; }
//获得高度
inline int getHeight(void){ return m_nHeight; }
//获得位深度
inline int getDeep(void){ return m_nDeep; }
//获得一行字节数
inline int getWidthBytes(void){ return m_nWidthBytes; }
protected://成员
HBITMAP m_hDibBmp;
BYTE *m_pBmpData;//指向位图数据
int m_nWidth; //宽度。(单位:像素pixel)
int m_nHeight; //高度。pixel
int m_nDeep; //深度。bit。深度必须大于24位
int m_nWidthBytes;//一行所需的字节数。必须是4字节的整数倍。
};
[cpp] view
plaincopy
#include <Windows.h>
#include <stdio.h>
#include <cassert>
#include "DIBBitmap.h"
class FileHoder
{
FILE *m_pFile;
public:
FileHoder(FILE *pFile)
: m_pFile(pFile)
{}
~FileHoder()
{
if (m_pFile) fclose(m_pFile);
}
};
//////////////////////////////////////////////////////////////////////////
CDIBBitmap::CDIBBitmap(void)
{
m_hDibBmp = NULL;
m_pBmpData = NULL;
m_nWidth = 0; //宽度。(单位:像素pixel)
m_nHeight = 0; //高度。pixel
m_nDeep = 0; //深度。bit。深度必须大于24位
m_nWidthBytes = 0;
}
CDIBBitmap::~CDIBBitmap(void)
{
clear();
}
bool CDIBBitmap::create(HDC hdc, int width, int height, int deep)
{
clear();
m_nWidth = width;
m_nHeight = height;
m_nDeep = deep;
m_nWidthBytes = ((m_nWidth*m_nDeep / 8 + 3) / 4) * 4;
m_pBmpData = nullptr;
BITMAPINFO bmInfo;
memset(&bmInfo, 0, sizeof(bmInfo));
bmInfo.bmiHeader.biSize = sizeof(bmInfo);
bmInfo.bmiHeader.biWidth = m_nWidth;
bmInfo.bmiHeader.biHeight = m_nHeight;
bmInfo.bmiHeader.biPlanes = 1;
bmInfo.bmiHeader.biBitCount = m_nDeep;
bmInfo.bmiHeader.biCompression = BI_RGB;
//如果创建成功,m_pBmpData将指向位图的像素区域。
m_hDibBmp = CreateDIBSection(hdc, &bmInfo, DIB_RGB_COLORS, (void**) &m_pBmpData, NULL, 0);
if (m_hDibBmp == NULL)
{
return false;
}
return true;
}
bool CDIBBitmap::create(HDC hDC, HBITMAP hBitmap)
{
if (NULL == hDC || NULL == hBitmap)
{
return false;
}
//获得位图信息
BITMAP bm;
GetObject(hBitmap, sizeof(bm), &bm);
//创建位图
if (!create(hDC, bm.bmWidth, bm.bmHeight, bm.bmBitsPixel))
{
return false;
}
//获得hBitmap数据,并拷贝给Dib位图
GetBitmapBits(hBitmap, bm.bmWidthBytes*bm.bmHeight, getBmpData());
return true;
}
void CDIBBitmap::clear(void)
{
if (m_hDibBmp != NULL)
{
DeleteObject(m_hDibBmp);
}
m_hDibBmp = NULL;
m_pBmpData = NULL;
}
void CDIBBitmap::sampleRender(HDC hDC, int x, int y)
{
if (!m_hDibBmp) return;
 
1d831
;
HDC memDC = CreateCompatibleDC(0);
SelectObject(memDC, m_hDibBmp);
BitBlt(hDC, x, y, m_nWidth, m_nHeight, memDC, 0, 0, SRCCOPY);
DeleteDC(memDC);
}
bool CDIBBitmap::load(HDC hDC, char *szFileName)
{
assert(hDC && szFileName && "CDIBBitmap::load");
FILE *fp = NULL;
fopen_s(&fp, szFileName, "rb");
if (NULL == fp)
{
return false;
}
FileHoder holder(fp);
//读入文件头
BITMAPFILEHEADER bmheader;
if (fread(&bmheader, sizeof(bmheader), 1, fp) != 1)
{
return false;
}
//无效的位图文件
if (bmheader.bfType != 0x4d42)
{
return false;
}
//读入位图信息头
BITMAPINFOHEADER bmInfo;
if (fread(&bmInfo, sizeof(bmInfo), 1, fp) != 1)
{
return false;
}
//注:目前程序不支持调色板数据位图加载。
if (bmInfo.biBitCount < 16)
{
return false;
}
//创建DIB位图
if (!create(hDC, bmInfo.biWidth, bmInfo.biHeight, bmInfo.biBitCount))
{
return false;
}
//定位到像素数据
fseek(fp, bmheader.bfOffBits, SEEK_SET);
//读入像素数据
if (fread(m_pBmpData, m_nWidthBytes, m_nHeight, fp) != m_nHeight)
{
return false;
}
return true;
}
bool CDIBBitmap::save(char *szFileName)
{
assert(szFileName && "CDIBBitmap::save");
if (NULL == m_hDibBmp || NULL == m_pBmpData)
{
return false;
}
FILE *fp = NULL;
fopen_s(&fp, szFileName, "wb");
if (NULL == fp)
{
return false;
}
FileHoder hoder(fp);
BITMAPFILEHEADER bmheader;
memset(&bmheader, 0, sizeof(bmheader));
bmheader.bfType = 0x4d42; //图像格式。必须为'BM'格式。
bmheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); //从文件开头到数据的偏移量
bmheader.bfSize = m_nWidthBytes*m_nHeight + bmheader.bfOffBits;//文件大小
BITMAPINFOHEADER bmInfo;
memset(&bmInfo, 0, sizeof(bmInfo));
bmInfo.biSize = sizeof(bmInfo);
bmInfo.biWidth = m_nWidth;
bmInfo.biHeight = m_nHeight;
bmInfo.biPlanes = 1;
bmInfo.biBitCount = m_nDeep;
bmInfo.biCompression = BI_RGB;
fwrite(&bmheader, sizeof(bmheader), 1, fp);
fwrite(&bmInfo, sizeof(bmInfo), 1, fp);
for (int i = 0; i < m_nHeight; ++i)
{
int index = m_nWidthBytes*i;
fwrite(m_pBmpData + index, m_nWidthBytes, 1, fp);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
截图功能参考代码:
[cpp] view
plaincopy
//获得设备描述表
m_hDeviceContext=GetDC(m_hWnd);
//创建掩码dc
m_hBackDC=CreateCompatibleDC(m_hDeviceContext);
//创建掩码位图
m_bBackBitmap=CreateCompatibleBitmap(m_hDeviceContext,m_nWidth,m_nHeight);
SelectObject(m_hBackDC,m_bBackBitmap);
...
将m_hDeviceContext的内容使用BitBlt拷贝给m_hBackDC
...
CDIBBitmap bmp;
if(!bmp.create(m_hBackDC,m_bBackBitmap))
{
g_log.write("截图失败!");
}
else
{
CreateDirectory(TEXT("shot"),NULL);
char buffer[64];
SYSTEMTIME tm;
GetLocalTime(&tm);
sprintf_s(buffer,64,"shot/%d_%d_%d_%d_%d_%d.bmp",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
if(!bmp.save(buffer))
{
g_log.writex("保存位图【%s】失败!",buffer);
}
}
相关文章推荐
- Bitmap位图文件读取、保存、屏幕截图
- 保存dc内容为bmp文件 ,屏幕截图也可以(zt)
- DIB位图文件的格式、读取、保存和显示(转载)
- DIB位图(Bitmap)的读取和保存
- DIB位图(Bitmap)的读取和保存
- 用java实现print screen,读取位图文件,将位图文件转化位jpeg格式并保存成文件输出!
- MFC中怎样将位图写入指定的Picture控件中,两种方式:1 加载已有位图 2读取位图文件;另外CreateDIBitmap的用法和StretchDIBits用法举例
- MFC 使用CImage获取到屏幕截图,指定格式保存到文件
- DIB位图文件的格式、读取、保存和显示
- VC屏幕截图,保存为Bmp文件
- VC屏幕截图 ,保存成本地文件
- BITMAP位图文件保存方法
- 如何将OpenGL中的场景保存为Bitmap位图文件
- android bitmap保存为文件及读取
- MFC屏幕截图,并保存成文件
- ios-day15-04(Quartz 2D之屏幕截图、并将截图保存到文件中)
- WinCE实现屏幕截图并保存为BMP文件
- C#读取Win32标准DLL文件中的Bitmap(位图)
- OpenGL加载、显示、截图、保存位图文件
- DIB位图文件的格式、读取、保存和显示