场景:

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到文件-保存屏幕内容到文件]的更多相关文章

  1. [Windows]_[中级]_[崩溃报告的中级解决方案]

    场景 1.在Windows上用C/C++开发软件, 经常会出现软件级别的崩溃情况, 如果用户看到这种崩溃报告, 那么一般会认为软件质量不高, 从而不想用. Windows上就会有崩溃报告这种噢给你工具 ...

  2. 使用C#+EmguCV处理图像入门(图像读取_显示_保存)二

    上个随笔已经介绍EmguCV的一些常用库和程序安装以及环境变量的配置,这次写的是如何使用这个类库对图像进行操作. EmguCV图像处理系统组成(个人见解): 图像的基本操作: 贴个代码: using ...

  3. 转:HIBERNATE一些_方法_@注解_代码示例---写的非常好

    HIBERNATE一些_方法_@注解_代码示例操作数据库7步骤 : 1 创建一个SessionFactory对象 2 创建Session对象 3 开启事务Transaction : hibernate ...

  4. 软件测试_Loadrunner_APP测试_性能测试_脚本优化_脚本回放

    本文主要写一下在使用Loadrunner录制完毕APP脚本之后如何对脚本进行回放,如有不足,欢迎评论补充. 如没有安装Loadrunner软件,请查看链接:软件测试_测试工具_LoadRunner: ...

  5. 软件测试_Loadrunner_APP测试_性能测试_脚本录制_基本操作流程

    这次主要是写一下使用Loadrunner对APP进行性能测试的基本流程,有关性能测试监控指标请查看链接:软件测试_性能测试_关注点. 先决条件:已安装Loadrunner.如未安装,请查看链接:软件测 ...

  6. 10.5 android输入系统_Reader线程_使用EventHub读取事件和核心类及配置文件_实验_分析

    4. Reader线程_使用EventHub读取事件 使用inotify监测/dev/input下文件的创建和删除 使用epoll监测有无数据上报 细节: a.fd1 = inotify_init(& ...

  7. day18_文件处理_迭代器_生成器

    #!/usr/bin/env python # -*- coding:utf-8 -*- # ********************day18_文件处理_迭代器_生成器 ************** ...

  8. 数据挖掘-diabetes数据集分析-糖尿病病情预测_线性回归_最小平方回归

    # coding: utf-8 # 利用 diabetes数据集来学习线性回归 # diabetes 是一个关于糖尿病的数据集, 该数据集包括442个病人的生理数据及一年以后的病情发展情况. # 数据 ...

  9. Update(Stage4):spark_rdd算子:第2节 RDD_action算子_分区_缓存:缓存、Checkpoint

    4. 缓存 概要 缓存的意义 缓存相关的 API 缓存级别以及最佳实践 4.1. 缓存的意义 使用缓存的原因 - 多次使用 RDD 需求: 在日志文件中找到访问次数最少的 IP 和访问次数最多的 IP ...

随机推荐

  1. [hihoCoder] #1032 : 最长回文子串

    时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这 ...

  2. linux快速进入全屏命令行模式

    按CTRL+ALT+F1~6就可以了.F7是桌面环境.

  3. Python中if __name__ == '__main__':作用

    #hello.pydef sayHello(): str="hello" print(str); if__name__=="__main__": print ( ...

  4. 使用 Electron 构建桌面应用(拖动控制篇)

    使用 Electron 构建桌面应用(拖动控制篇) 当窗口被定义了大小,我们也就是在自定义这个窗口,使得它不可拉伸没有框架,让它看起来就像一个真正的声效器浮在桌面上. 现在问题来了 – 要如何移动或者 ...

  5. Office 2013 Excel 打开文档很慢很慢的解决方法

    这个问题查了很多案例,试了很多方法,但是只有下面这个方法有用! 这几天打开excel文档很慢很慢,双击之后好久没反应,过会儿它才慢慢冒出来,当时将就了,刚刚休息的时候想着查一下吧,不然很影响工作效率! ...

  6. flask中的g、add_url_rule、send_from_directory、static_url_path、static_folder的用法

    Flask中的g对象是个很好的东西,主要用于在一个请求的过程中共享数据.可以随意给g对象添加属性来保存数据,非常的方便,下面的代码是一个使用g对象的例子.下面的这个例子会使用random随机产生一个0 ...

  7. json关键总结

    先引用 Newtonsoft.Json.Net20.dll //序列化对象的方法也非常的简单: string json = JsonConvert.SerializeObject(product); ...

  8. 【WPF】设置TextBox内容为空时的提示文字

    <TextBox Width="150" Margin="5"> <TextBox.Resources> <VisualBrush ...

  9. C语言 · s01串

    算法训练 s01串   时间限制:1.0s   内存限制:256.0MB      问题描述 s01串初始为"0" 按以下方式变换 0变1,1变01 输入格式 1个整数(0~19) ...

  10. Fastjson 的简单使用<转>

    简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库. 高性能 fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson. ...