将HBITMAP保存为文件_hbitmap 保存文件-程序员宅基地

技术标签: MFC/VC++  file  null  bi  colors  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

bool HBITMAPToBmp ( HBITMAP hBitmap , const CString & strFileName

)

{

 

 

if ( hBitmap == NULL

)

 

 

return false

;

 

 

HDC hDC

;

 

 

int iBits ;

//当前分辨率下每象素所占字节数

 

 

WORD wBitCount ;

//位图中每象素所占字节数

 

 

DWORD dwPaletteSize =0;

//定义调色板大小

 

 

DWORD dwBmBitsSize =0;

//位图中像素字节大小

 

 

DWORD dwDIBSize =0;

//位图文件大小

 

 

DWORD dwWritten =0;

//位图文件大小 写入文件字节数

 

 

BITMAP Bitmap ;

//位图属性结构

 

 

BITMAPFILEHEADER bmfHdr ;

//位图文件头结构

 

 

BITMAPINFOHEADER bi ;

//位图信息头结构

 

 

LPBITMAPINFOHEADER lpbi = NULL ;

//指向位图信息头结构

 

 

HANDLE hDib , hPal , hOldPal = NULL ;

//定义文件,分配内存句柄,调色板句柄

 

 

//计算位图文件每个像素所占字节数

 

 

hDC = CreateDC ( _T ( "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

 

 

wBitCount

= 24;

 

 

GetObject ( hBitmap , sizeof ( Bitmap ),( LPSTR )& Bitmap

);

 

 

bi . biSize = sizeof ( BITMAPINFOHEADER

);

 

 

bi . biWidth = Bitmap . bmWidth

;

 

 

bi . biHeight = Bitmap . bmHeight

;

 

 

if ( Bitmap . bmWidth < 100 || Bitmap . bmHeight

< 100)

 

 

return false

;

 

 

bi . biPlanes

= 1;

 

 

bi . biBitCount = wBitCount

;

 

 

bi . biCompression = BI_RGB

;

 

 

bi . biSizeImage

= 0;

 

 

bi . biXPelsPerMeter

= 0;

 

 

bi . biYPelsPerMeter

= 0;

 

 

bi . biClrImportant

= 0;

 

 

bi . biClrUsed

= 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

);

}

 

 

//获取该调色板下新的像素值

 

 

int nRet = GetDIBits ( hDC

,

 

 

hBitmap

,

0,

(

 

UINT ) Bitmap . bmHeight

,

(

 

LPSTR ) lpbi + sizeof ( BITMAPINFOHEADER )+ dwPaletteSize

,

(

 

BITMAPINFO *) lpbi

,

 

 

DIB_RGB_COLORS

);

 

 

if (0 == nRet

)

{

 

 

nRet

= 0;

}

 

 

//恢复调色板

 

 

if ( hOldPal

)

{

::

 

SelectPalette ( hDC , ( HPALETTE ) hOldPal , TRUE

);

 

 

RealizePalette ( hDC

);

::

 

ReleaseDC ( NULL , hDC

);

}

 

 

//设置位图文件头

 

 

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

;

 

 

//创建位图文件

 

 

HANDLE fh = CreateFile ( strFileName . operator LPCTSTR (), GENERIC_WRITE ,0, NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN , NULL

);

 

 

if ( fh == INVALID_HANDLE_VALUE

)

{

 

 

int x = GetLastError

();

 

 

GlobalUnlock ( hDib

);

 

 

GlobalFree ( hDib

);

 

 

return FALSE

;

}

 

 

//写入位图文件头

 

 

WriteFile ( fh , ( LPSTR )& bmfHdr , sizeof ( BITMAPFILEHEADER ), & dwWritten , NULL

);

 

 

//写入位图文件其余内容

 

 

WriteFile ( fh , ( LPSTR ) lpbi , dwDIBSize - sizeof ( BITMAPFILEHEADER ), & dwWritten , NULL

);

 

 

//清除

 

 

CloseHandle ( fh

);

 

 

GlobalUnlock ( hDib

);

 

 

GlobalFree ( hDib

);

 

 

return true

;

}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/robinjwong/article/details/4704776

智能推荐

面试高频手撕题 | 09.将两个有序数组合并成一个有序数组_开合跳、色盲测试、展示手心手背-程序员宅基地

文章浏览阅读842次,点赞23次,收藏18次。一、知识点斐波那契数列(Fibonacci sequence),又称黄金分割数列,是一个经典的数学数列,起始于 0 和 1,后续的每一项都是前两项的和。指针指向下一个节点,从而形成链表。一、知识点归并排序:归并排序(Merge sort)是建立在归并操作上的一种有效、稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一。//这题我写的非常恼火,有时候题目整的的谜语人一样,例子也不能多给几个,就靠提交的过程中遇到的错误去判错,简直是一种侮辱package mainimport (_开合跳、色盲测试、展示手心手背

C++数字图像处理篇之图像加马赛克_mfc马赛克-程序员宅基地

文章浏览阅读5.4k次,点赞4次,收藏15次。马赛克是一种广为使用的图像处理手段,它是将影像特定区域的色阶细节劣化并造成色块打乱的效果。这种模糊看样子像一个个小格子,所以被称为马赛克。马赛克主要的目的就是使图像内容无法辨认,以保护特殊图像内容。这样的例子我们经常遇到,例如在新闻中保护当事人的隐私。图像加马赛克类似与图像重采样。我们在实验中采用的算法就是比较简单的加马赛克的算法,就是按固定间隔取像素点,将图片分割成一些嗯小块,每个小块的灰度..._mfc马赛克

Linux>命令参数介绍_linux >> 参数-程序员宅基地

文章浏览阅读169次。ls 命令常用选项及功能ls命令的基本格式 ls [选项] 目录名称选项功能-a显示全部的文件,包括隐藏文件(开头为 . 的文件)也一起罗列出来,这是最常用的选项之一。-A显示全部的文件,连同隐藏文件,但不包括 . 与 … 这两个目录。-d仅列出目录本身,而不是列出目录内的文件数据。-fls 默认会以文件名排序,使用 -f 选项会直接列出结果..._linux >> 参数

以太网 知识-MII接口 RMII / SMII接口 MII / RGMII接口_mii/rmii怎么接两个phy-程序员宅基地

文章浏览阅读2w次。本文主要分析MII/RMII/SMII,以及GMII/RGMII/SGMII接口的信号定义,及相关知识,同时本文也对RJ-45接口进行了总结,分析了在10/100模式下和1000M模式下的设计方法。1. MII接口分析 MII接口提供了MAC与PHY之间、PHY与STA(Station Management)之间的互联技术,该接口支持10Mb/s与100Mb/s的数据传输速率,数据传输的位宽为4位。 提到MII,就有可能涉及到RS,PLS,STA等名词术语,下面讲一下他们之间对应的关系_mii/rmii怎么接两个phy

K210 图像识别 (加训练模型)_k210图像识别-程序员宅基地

文章浏览阅读3.4w次,点赞85次,收藏742次。以管理员的方式运行下载模式 高速改为低速模式_k210图像识别

解决Unity开启多个协程卡顿问题_unity 多个协程-程序员宅基地

文章浏览阅读3.1k次。Unity开启多个协程往往造成卡顿,因此需要每完成一个协程再新开启一个协程。for (int i = 0; i < result.result.Count; i++) { try { BaseStation responses = JsonMapper.ToObject<BaseStation>(JsonMapper.ToJson(result.result[i])); ..._unity 多个协程

随便推点

计算机操作系统第三章自测题-处理机调度与死锁-程序员宅基地

文章浏览阅读1.7k次,点赞2次,收藏20次。1、在单处理器的多进程系统中,进程什么时候占有处理器以及决定占用时间的长短是由( )决定的。A、进程运行时间    B、进程的特点和进程调度策略C、进程执行的代码   D、进程完成什么功能进程调度的时机与进程特点有关,如进程是否为CPU繁忙型还是I/O繁忙型、自身的优先级等。但是仅这些特点是不够的,能否得到调度还取决于进程调度策略,若采用优先级调度算法,则进程的优先级才起作用。..._在选择处理器调度算法时,为了使短作业、长作业及交互作业用户都比较满意,应采用( ).a基于优先权的剥夺调度算法b响应比优先算法c时间片轮转法d多级反馈队列调度算法e短作业优先调度算法ffcfs调度算法

[MySQL] 查看正在执行的sql语句 show processlist_show processlist 能显示sql 语句吗-程序员宅基地

文章浏览阅读8.9k次。processlist命令的输出结果显示了有哪些线程在运行可以帮助识别出有问题的查询语句,两种方式使用这个命令。 1. 进入mysql/bin目录下输入mysql admin processlist; 2. 启动mysql,输入show processlist; 如果有SUPER权限,则可以看到全部的线程,否则,只能看到自己发起的线程(这是指,当前对应的MySQL帐户..._show processlist 能显示sql 语句吗

小学生学python到底能干什么-颤抖 | 小学生都开始学Python了,十年后你还有工作么?...-程序员宅基地

文章浏览阅读156次。原标题:颤抖 | 小学生都开始学Python了,十年后你还有工作么?今 日 摘 要AI火爆全球,Python技能需求达到174%!小学生已经开始学Python,还成为高考必备项目,十年后你还有工作么?今日活动:Python数据学习交流群进群福利:超过10万人下载的10本最火数据书籍+ 1000+Python高清教学视频+ Python数据分析工具书+ 名企导师专场AI & Python专场讲座德勤...

《鸟哥的Linux私房菜》第四版导学_好了a18第四-程序员宅基地

文章浏览阅读1.1w次。鸟哥的Linux私房菜0、计算机概论0.1、电脑:辅助人脑的好工具(什么是电脑?什么是计算机a3)0.1.1、电脑硬件的五大单元(电脑硬件大致可分为三个部分b3)(什么是CPU a4)(CPU主要的组成部分b4)(算术逻辑单元的功能c4)(控制单元的功能d4)(CPU读取的数据来源e4)(电脑硬件的五个组成部分f4)(数据在内存流动的基本知识g4)0.1.2、一切设计的起点:CPU架构(常见的两种CPU架构a5)(世界上使用最广的CPU b5)(常见的RISC指令集CPU c5)(常见的CISC指_好了a18第四

卡莱特led显示屏调试教程_卡莱特A接收卡调屏步骤-程序员宅基地

文章浏览阅读3.8k次。卡莱特5A接收卡调屏步骤卡莱特5A接收卡支持千兆网卡和发送卡两种发送方式,两种方式在5A接收卡的设置方面步骤相似,本文将讲述在千兆网卡发送条件下,5A接收卡的参数设置步骤。一、硬件连接1、发送卡连接图详见《卡莱特发送卡设备连接操作》2、千兆网卡连接图千兆网卡连接拓扑图千兆网卡硬件连接注意事项:a)电脑网卡必须是千兆网卡;b)电脑千兆网卡驱动必须安装正确;c)千兆网卡与5A接收卡、5A接收卡之间的网..._卡莱特指示灯

react Link跳转无效_React Native开发之react-navigation详解-程序员宅基地

文章浏览阅读299次。众所周知,在多页面应用程序中,页面的跳转是通过路由或导航器来实现的。在0.44版本之前,开发者可以直接使用官方提供的Navigator组件来实现页面的跳转,不过从0.44版本开始,Navigator被官方从react native的核心组件库中剥离出来,放到react-native-deprecated-custom-components的模块中。 如果开发者需要继续使用Navigator,则需要..._react navigate(-1) url不生效

推荐文章

热门文章

相关标签