[ATL/WTL]_[中级]_[保存CBitmap到文件-保存屏幕内容到文件]
场景:
1. 在做图片处理时,比方放大后或加特效后须要保存CBitmap(HBITMAP)到文件.
2.截取屏幕内容到文件时.
3.不须要增加第3方库时.
说明: 这段代码部分来自网上。第一次学atl/wtl。gdi不是非常熟悉。以后转换为wtl版本号吧。
当然wtl项目直接用也没问题. 如今想想wxWidgets的wxImage类对这类操作方便多了。仅仅须要调用一个SaveFile方法。
保存HBITMAP到文件:
static bool SaveBitmapToFile(CBitmap& bitmap, LPWSTR lpFileName)
{
HBITMAP hBitmap; // 为刚才的屏幕位图句柄
HDC hDC; //设备描写叙述表
int iBits; //当前显示分辨率下每一个像素所占字节数
WORD wBitCount; //位图中每一个像素所占字节数
DWORD dwPaletteSize = 0, //定义调色板大小
dwBmBitsSize, //位图中像素字节大小
dwDIBSize, //位图文件大小
dwWritten; //写入文件字节数
BITMAP Bitmap; //位图属性结构
BITMAPFILEHEADER bmfHdr; //位图文件头结构
BITMAPINFOHEADER bi; //位图信息头结构
LPBITMAPINFOHEADER lpbi; //指向位图信息头结构
HANDLE fh, //定义文件
hDib, //分配内存句柄
hPal, //调色板句柄
hOldPal = NULL; //计算位图文件每一个像素所占字节数
hBitmap = bitmap;
hDC = CreateDC(L"DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC); if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else if (iBits <= 24)
wBitCount = 24;
else if (iBits <= 32)
wBitCount = 32; //计算调色板大小
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(NULL);
hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
} // 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
(LPSTR)lpbi + sizeof (BITMAPINFOHEADER) + dwPaletteSize,
(LPBITMAPINFO)lpbi, DIB_RGB_COLORS); //恢复调色板
if (hOldPal)
{
SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, 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;
}
保存屏幕到文件:
static void SaveScreenToFile(LPCTSTR szFileName)
{
HDC hScrDC = ::GetDC(NULL);
HDC hMemDC = NULL; BYTE *lpBitmapBits = NULL; int nWidth = GetSystemMetrics(SM_CXSCREEN);
int nHeight = GetSystemMetrics(SM_CYSCREEN); hMemDC = ::CreateCompatibleDC(hScrDC); BITMAPINFO bi;
ZeroMemory(&bi, sizeof(BITMAPINFO));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = nWidth;
bi.bmiHeader.biHeight = nHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 24; HBITMAP bitmap = ::CreateDIBSection(hMemDC, &bi, DIB_RGB_COLORS, (LPVOID*)&lpBitmapBits, NULL, 0);
HGDIOBJ oldbmp = ::SelectObject(hMemDC, bitmap); ::BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, 0, 0, SRCCOPY); BITMAPFILEHEADER bh;
ZeroMemory(&bh, sizeof(BITMAPFILEHEADER));
bh.bfType = 0x4d42; //bitmap
bh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bh.bfSize = bh.bfOffBits + ((nWidth*nHeight)*3); FILE* file = _wfopen(szFileName,L"wb");
if(file)
{
fwrite(&bh,1,sizeof(BITMAPFILEHEADER),file);
fwrite(&(bi.bmiHeader),1,sizeof(BITMAPINFOHEADER),file);
fwrite(lpBitmapBits,1,3 * nWidth * nHeight,file);
fclose(file);
} ::SelectObject(hMemDC, oldbmp);
::DeleteObject(bitmap);
::DeleteObject(hMemDC);
::ReleaseDC(NULL, hScrDC);
}
[ATL/WTL]_[中级]_[保存CBitmap到文件-保存屏幕内容到文件]的更多相关文章
- [Windows]_[中级]_[崩溃报告的中级解决方案]
场景 1.在Windows上用C/C++开发软件, 经常会出现软件级别的崩溃情况, 如果用户看到这种崩溃报告, 那么一般会认为软件质量不高, 从而不想用. Windows上就会有崩溃报告这种噢给你工具 ...
- 使用C#+EmguCV处理图像入门(图像读取_显示_保存)二
上个随笔已经介绍EmguCV的一些常用库和程序安装以及环境变量的配置,这次写的是如何使用这个类库对图像进行操作. EmguCV图像处理系统组成(个人见解): 图像的基本操作: 贴个代码: using ...
- 转:HIBERNATE一些_方法_@注解_代码示例---写的非常好
HIBERNATE一些_方法_@注解_代码示例操作数据库7步骤 : 1 创建一个SessionFactory对象 2 创建Session对象 3 开启事务Transaction : hibernate ...
- 软件测试_Loadrunner_APP测试_性能测试_脚本优化_脚本回放
本文主要写一下在使用Loadrunner录制完毕APP脚本之后如何对脚本进行回放,如有不足,欢迎评论补充. 如没有安装Loadrunner软件,请查看链接:软件测试_测试工具_LoadRunner: ...
- 软件测试_Loadrunner_APP测试_性能测试_脚本录制_基本操作流程
这次主要是写一下使用Loadrunner对APP进行性能测试的基本流程,有关性能测试监控指标请查看链接:软件测试_性能测试_关注点. 先决条件:已安装Loadrunner.如未安装,请查看链接:软件测 ...
- 10.5 android输入系统_Reader线程_使用EventHub读取事件和核心类及配置文件_实验_分析
4. Reader线程_使用EventHub读取事件 使用inotify监测/dev/input下文件的创建和删除 使用epoll监测有无数据上报 细节: a.fd1 = inotify_init(& ...
- day18_文件处理_迭代器_生成器
#!/usr/bin/env python # -*- coding:utf-8 -*- # ********************day18_文件处理_迭代器_生成器 ************** ...
- 数据挖掘-diabetes数据集分析-糖尿病病情预测_线性回归_最小平方回归
# coding: utf-8 # 利用 diabetes数据集来学习线性回归 # diabetes 是一个关于糖尿病的数据集, 该数据集包括442个病人的生理数据及一年以后的病情发展情况. # 数据 ...
- Update(Stage4):spark_rdd算子:第2节 RDD_action算子_分区_缓存:缓存、Checkpoint
4. 缓存 概要 缓存的意义 缓存相关的 API 缓存级别以及最佳实践 4.1. 缓存的意义 使用缓存的原因 - 多次使用 RDD 需求: 在日志文件中找到访问次数最少的 IP 和访问次数最多的 IP ...
随机推荐
- 苹果开发小记(一):NSString 的比较用法
转自:http://blog.sina.com.cn/s/blog_897dd7be0100teh6.html 做了几个月的苹果,很多的思想方法都可以遵循一定规律来做的.NSString 比较字符串, ...
- 服务器swap
交换区(swap)是存在于高速存储设 备上的一块区域,是虚拟内存系统重要的组成部分.通过交换区,我们不再局限于有限的物理内存空间,理论上可以无限地扩大虚拟内存系统,从而运行更多的程 序,进行更多的业务 ...
- gnome3增加自定义程序快捷方式
gnome3增加自定义程序快捷方式 1. 安装alacarte 在命令行输入下列命令安装alacarte程序 yum -y install alacarte 安装完毕后,在命令行输入下 ...
- 检测SqlServer数据库是否能连接的小技巧
有时候可能需要检测下某台机器的服务是不是起来了,或者某台机器的某个库是不是能被连接又不能打开ssms也不想登陆服务器的话就可以用这个方法. 1.在桌面上右键创建个文本,然后改后缀名为udl以后保存(1 ...
- 一款由jquery实现的超炫的页面加载特效
今天为大家带来一款由jquery实现的超炫的页面加载特效.连续的几个页面分开特效.最后由三维的线条由远至近消失,然后由近至远出现.效果超级梦炫.一起看下效果图: 在线预览 源码下载 实现的代码. ...
- 使用Windows防火墙禁止Ping入
前言: 不知道安全比赛是咋样的,但是肯定是日来日去的,那么故事来了,大牛们肯定会狂ip,刚开始肯定是一个段的狂扫.咋让他不扫到你呢?就是这篇文章了.其实这一切都是ICMP在作祟 windows2003 ...
- mysql 的一点点记录
以后再来整理. -- 查询一个学校的报修单数 SELECT s.id AS schoolId , -- 学校ID COUNT(i.id) as cntId, -- 报修单数 IFNULL(t1.noh ...
- C#基础-获得当前程序的 空间名.类名.方法名
string typeName = this.GetType().ToString();//空间名.类名 string typeName = this.GetType().Name;//类名 new ...
- xml选择节点方法
1.选取某个节点 方法一:newNode = document.DocumentElement.SelectSingleNode("//student[@id='A103']"); ...
- Maven学习:项目之间的关系
Maven不仅可以定义一个项目中各个模块之间的关系,还可以更延伸一步定义项目与项目之间的关系. 定义父子项目的好处还是挺多的.